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

6

我通过阅读显示所有全局变量/本地变量的帖子得知,在gdb命令行中可以获取当前帧的所有变量。

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

2个回答

4
问题是否改变?我不确定,但我怀疑是的,因为我的先前答案是非常错误的。我依稀记得这个问题曾经是关于全局变量的,如果是这样的话,那么这是正确的:

我认为没有办法。 GDB符号表仅部分暴露给Python,我相信无法迭代它们是其中的一个缺陷。

然而,从Python中很容易迭代本地变量。您可以使用gdb.selected_frame()获取所选帧。然后,您可以使用block()方法从帧中获取Block对象。Block对象表示一个范围。您可以直接遍历Block以获取该范围的变量。然后,使用Block.superblock上升一个作用域。当您遇到具有function属性的块时,您已进入函数的最外层作用域。

+1. 我已经使用这个作为起点编写了一个脚本。如果我搞砸了什么,请告诉我 :-) https://dev59.com/6Irda4cB1Zd3GeqPMGtP#31231722 - Ciro Santilli OurBigBook.com
你不想像那样在集合中存储名称——如果你看到多个相同的名称,那是由于遮蔽。它们不是重复的。 - Tom Tromey
谢谢,我明白了。我的目标是回答“所有可见变量及其当前值是什么?”我不确定这是否是OP想要的,但这应该是一个常见的用例。但是,info locals也会显示父级框架。 - Ciro Santilli OurBigBook.com

4
这篇文章展示了如何根据Tom的建议列出所有当前可见的变量。它仅显示在当前文件中定义的全局变量,因为正如Tom所提到的,目前无法访问其他文件中定义的全局变量。我们在集合中存储已经看到的名称,并在块树上向上移动。请注意,info locals会显示父帧上被遮蔽的变量。如果想要显示这些变量,请删除set检查。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;
}

使用方法:

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

输出:

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上进行测试。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接