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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With