获取gdb的python接口中的所有全局变量/局部变量

时间:2022-12-24 16:49:44

I have learned throw reading Printing all global variables/local variables that we can get all variables of the current frame in gdb's command line.

我已经学会了读取打印所有全局变量/局部变量,我们可以在gdb的命令行中获取当前帧的所有变量。

My question is how to get all variables of the current frame in the gdb's python interface, since info locals just give results in strings and that's not convenient for further use.

我的问题是如何在gdb的python接口中获取当前帧的所有变量,因为info locals只是在字符串中给出结果,这不便于进一步使用。

2 个解决方案

#1


Did the question change? I'm not sure, but I suspect so since my previous answer is very wrong. I vaguely recall that the question used to be about global variables, in which case this is true:

这个问题改变了吗?我不确定,但我怀疑,因为我之前的回答是非常错误的。我含糊地回忆起过去的问题是全局变量,在这种情况下这是真的:

I don't think there is a way. GDB symbol tables are only partially exposed to Python, and I believe the lack of an ability to iterate over them is one of the holes.

我认为没有办法。 GDB符号表只是部分暴露给Python,我相信缺乏迭代它们的能力是其中一个漏洞。

However, it is easy to iterate over the local variables from Python. You can use gdb.selected_frame() to get the selected frame. Then, from the frame you can you use the block() method to get the Block object.

但是,很容易从Python迭代局部变量。您可以使用gdb.selected_frame()来获取所选帧。然后,从框架中可以使用block()方法获取Block对象。

A Block object represents a scope. You can iterate over the Block directly to get the variables from that scope. Then, go up a scope using Block.superblock. When you hit a block with a function attribute, you've hit the outermost scope of the function.

Block对象表示范围。您可以直接迭代Block以从该范围获取变量。然后,使用Block.superblock上一个范围。当您使用函数属性命中某个块时,您已经触及该函数的最外层范围。

#2


This shows how to list all currently visible variables (once) based on Tom's suggestions.

这显示了如何根据Tom的建议列出所有当前可见的变量(一次)。

It only shows globals defined in the current file, since as Tom mentioned, it is currently not possible to access globals defined in other files.

它只显示当前文件中定义的全局变量,因为正如Tom所提到的,目前无法访问其他文件中定义的全局变量。

We store the names we've seen in a set and go up on the block tree.

我们将我们在一组中看到的名称存储在块树上。

Note that info locals shows shadowed variables on parent frames. To show those as well, just remove the set checks.

请注意,info locals在父帧上显示阴影变量。要显示这些,只需删除设置检查。

main.py:

gdb.execute('file a.out', to_string=True)
gdb.execute('break 10', to_string=True)
gdb.execute('run', to_string=True)
frame = gdb.selected_frame()
block = frame.block()
names = set()
while block:
    if(block.is_global):
        print()
        print('global vars')
    for symbol in block:
        if (symbol.is_argument or symbol.is_variable):
            name = symbol.name
            if not name in names:
                print('{} = {}'.format(name, symbol.value(frame)))
                names.add(name)
    block = block.superblock

main.c:

int i = 0;
int j = 0;
int k = 0;

int main(int argc, char **argv) {
    int i = 1;
    int j = 1;
    {
        int i = 2;
        i = 2; /* Line 10. Add this dummy line so above statement takes effect. */
    }
    return 0;
}

Usage

gcc -ggdb3 -O0 -std=c99 main.c
gdb --batch -q -x main.py

Output:

i = 2
argc = 1
argv = 0x7fffffffd718
j = 1

global vars
k = 0

If you also want constants like enum fields, also allow symbol.is_constant.

如果你还想要像枚举字段这样的常量,也允许使用symbol.is_constant。

Tested on Ubuntu 14.04, GDB 7.7.1, GCC 4.8.4.

在Ubuntu 14.04,GDB 7.7.1,GCC 4.8.4上测试。

#1


Did the question change? I'm not sure, but I suspect so since my previous answer is very wrong. I vaguely recall that the question used to be about global variables, in which case this is true:

这个问题改变了吗?我不确定,但我怀疑,因为我之前的回答是非常错误的。我含糊地回忆起过去的问题是全局变量,在这种情况下这是真的:

I don't think there is a way. GDB symbol tables are only partially exposed to Python, and I believe the lack of an ability to iterate over them is one of the holes.

我认为没有办法。 GDB符号表只是部分暴露给Python,我相信缺乏迭代它们的能力是其中一个漏洞。

However, it is easy to iterate over the local variables from Python. You can use gdb.selected_frame() to get the selected frame. Then, from the frame you can you use the block() method to get the Block object.

但是,很容易从Python迭代局部变量。您可以使用gdb.selected_frame()来获取所选帧。然后,从框架中可以使用block()方法获取Block对象。

A Block object represents a scope. You can iterate over the Block directly to get the variables from that scope. Then, go up a scope using Block.superblock. When you hit a block with a function attribute, you've hit the outermost scope of the function.

Block对象表示范围。您可以直接迭代Block以从该范围获取变量。然后,使用Block.superblock上一个范围。当您使用函数属性命中某个块时,您已经触及该函数的最外层范围。

#2


This shows how to list all currently visible variables (once) based on Tom's suggestions.

这显示了如何根据Tom的建议列出所有当前可见的变量(一次)。

It only shows globals defined in the current file, since as Tom mentioned, it is currently not possible to access globals defined in other files.

它只显示当前文件中定义的全局变量,因为正如Tom所提到的,目前无法访问其他文件中定义的全局变量。

We store the names we've seen in a set and go up on the block tree.

我们将我们在一组中看到的名称存储在块树上。

Note that info locals shows shadowed variables on parent frames. To show those as well, just remove the set checks.

请注意,info locals在父帧上显示阴影变量。要显示这些,只需删除设置检查。

main.py:

gdb.execute('file a.out', to_string=True)
gdb.execute('break 10', to_string=True)
gdb.execute('run', to_string=True)
frame = gdb.selected_frame()
block = frame.block()
names = set()
while block:
    if(block.is_global):
        print()
        print('global vars')
    for symbol in block:
        if (symbol.is_argument or symbol.is_variable):
            name = symbol.name
            if not name in names:
                print('{} = {}'.format(name, symbol.value(frame)))
                names.add(name)
    block = block.superblock

main.c:

int i = 0;
int j = 0;
int k = 0;

int main(int argc, char **argv) {
    int i = 1;
    int j = 1;
    {
        int i = 2;
        i = 2; /* Line 10. Add this dummy line so above statement takes effect. */
    }
    return 0;
}

Usage

gcc -ggdb3 -O0 -std=c99 main.c
gdb --batch -q -x main.py

Output:

i = 2
argc = 1
argv = 0x7fffffffd718
j = 1

global vars
k = 0

If you also want constants like enum fields, also allow symbol.is_constant.

如果你还想要像枚举字段这样的常量,也允许使用symbol.is_constant。

Tested on Ubuntu 14.04, GDB 7.7.1, GCC 4.8.4.

在Ubuntu 14.04,GDB 7.7.1,GCC 4.8.4上测试。