6

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.

Alex Ham
  • 151
  • 1
  • 12
TorosFanny
  • 1,702
  • 1
  • 16
  • 25

2 Answers2

4

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.

Tom Tromey
  • 21,507
  • 2
  • 45
  • 63
  • +1. I've made a script using this as starting point. Let me know if I've messed anything up :-) http://stackoverflow.com/a/31231722/895245 – Ciro Santilli OurBigBook.com Jul 05 '15 at 15:16
  • You don't want to store the names in a set like that -- if you see multiple identical names, it is due to shadowing. They aren't duplicates. – Tom Tromey Jul 06 '15 at 01:46
  • Thanks, I understand that. My goal was to answer "What are all visible variables and their current values?" I'm not sure if this is what the OP wants, but it should be a common use case. But true, `info locals` shows parent frames as well. – Ciro Santilli OurBigBook.com Jul 06 '15 at 05:33
4

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.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985