With the release of gdb version 7.0, the debugger gained support for python scripts. This means that we can extend gdb with out own commands or create functions to operate with data structures (lists, BLOBs, …)
There are several ways to write python scripts in gdb 7. The quickest is to type the ‘python’ command in gdb prompt, write our script and quit the prompt by typing ‘end’. The other method uses object filenames where you have an object ‘test1′ and the python script for the object is ‘test1-gdb.py’. If gdb finds such a file in the current path, it will automatically open it.
Let’s say we have a structure in our program:
struct _node {
int weight;
char tag[20];
};
We use the _node struct in out program:
int main () {
struct _node *mynode = malloc(sizeof(*mynode));
mynode->weight = 210;
strcpy(mynode->tag, “dummy node”);
free(mynode);
return 0;
}
When compiling the program and running it under gdb, we have to address the structure members by ourselves and sometime even convert them to an appropriate format. This might be acceptable if we operate with a single structure but what if we have a linked list or even a more complicated data structure? For a list we want to print out all the items in it. Doing that by hand would take unreasonable amount of time. Now gdb had scripting support before 7.0 but now we can do in in Python. This is pure awesomeness.
Back to the example. Out script looks like this:
import gdb
def print_node(value):
frame = gdb.selected_frame()
try:
val = gdb.Frame.read_var(frame, value)
except:
print “No such variable”
return
if str(val.type) == “struct _node *”:
print “Weight: ” + str(val["weight"])
print “Tag: ” + str(val["tag"])
else:
print “Is not a node (” + str(val.type) + “)”
Now we compile the program with debug support (-ggdb -O0) and start gdb.
(gdb) b main
Breakpoint 1 at 0×40056c: file test1.c, line 12.
(gdb) r
Starting program: /home/luka/test1Breakpoint 1, main () at test1.c:12
12 struct _node *mynode = malloc(sizeof(*mynode));
(gdb) n
14 mynode->weight = 210;
(gdb)
15 strcpy(mynode->tag, “dummy node”);
(gdb)
16 free(mynode);
(gdb) python print_node(“mynode”)
Weight: 210
Tag: “dummy node000000000000000000″
(gdb)