简体   繁体   中英

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

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

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.

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.

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.

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.

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

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.

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.

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 .

Tested on Ubuntu 14.04, GDB 7.7.1, GCC 4.8.4.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM