Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 834
TorosFanny Avatar asked May 03 '15 11:05

TorosFanny


People also ask

Can you access global variables in Python?

A global variable in Python is often declared as the top of the program. In other words, variables that are declared outside of a function are known as global variables. You can access global variables in Python both inside and outside the function.

Where local and global variables are stored in Python?

We have to declare local variables within a function, i.e., in the function body. We should declare global variables outside a function. Local variables are usually stored in stack section of the memory. Global variables are usually stored in the private heap section of the memory.

How do you access local variables outside a function in Python?

Using the global statement If you want to assign a value to a name defined outside the function, then you have to tell Python that the name is not local, but it is global. We do this using the global statement. It is impossible to assign a value to a variable defined outside a function without the global statement.


2 Answers

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.

like image 84
Tom Tromey Avatar answered Oct 09 '22 20:10

Tom Tromey


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.