关于C#:在gdb的python接口中获取所有全局变量/局部变量

Get all global variables/local variables in gdb's python interface

我学习了throw-reading打印所有全局变量/局部变量,我们可以在gdb的命令行中获取当前帧的所有变量。

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


问题变了吗?我不确定,但我怀疑是这样,因为我以前的回答是非常错误的。我隐约记得这个问题过去是关于全局变量的,在这种情况下,这是正确的:

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.

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

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


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

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

我们把看到的名字存储在一个集合中,然后放到树上。

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

MY.PY:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

主要内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
}

用法

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

输出:

1
2
3
4
5
6
7
i = 2
argc = 1
argv = 0x7fffffffd718
j = 1

global vars
k = 0

如果您还需要像enum字段这样的常量,也可以允许symbol.is_constant

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