It’s been a while since I last talked about Python scripting support in GDB. Mostly because I’ve been focusing on getting stuff from the branch merged into CVS HEAD, so that GDB 7.0 can have some useful Python bindings.
The latest two patches committed upstream are for creating convenience functions in Python, and fo manipulating a program’s stack frames as Python objects. So, what can you do with those? I’ll borrow an example from Tom Tromey here: suppose you want to set a breakpoint which triggers only when the code is called by one specific function. You can create a convenience function like this:
import gdb
import re
class CallerIs (gdb.Function):
"""Return True if the calling function's name is equal to a string.
This function takes one or two arguments.
The first argument is the name of a function; if the calling function's
name is equal to this argument, this function returns True.
The optional second argument tells this function how many stack frames
to traverse to find the calling function. The default is 1."""
def __init__ (self):
super (CallerIs, self).__init__ ("caller_is")
def invoke (self, name, nframes = 1):
frame = gdb.selected_frame ()
while nframes > 0:
frame = frame.older ()
nframes = nframes - 1
return frame.name () == name.string ()
CallerIs ()
And then create a conditional breakpoint using it, as in:
(gdb) break foo.c:42 if $caller_is ("some_function")
Or, to check the name of the grand-grand-caller of the code:
(gdb) break foo.c:42 if $caller_is ("some_function", 3)
Cool, huh? Now, why bother writing that big doc comment? GDB will use it as online help for the function you wrote:
(gdb) help function caller_is
Return True if the calling function's name is equal to a string.
This function takes one or two arguments.
The first argument is the name of a function; if the calling function's
name is equal to this argument, this function returns True.
The optional second argument tells this function how many stack frames
to traverse to find the calling function. The default is 1.
One other patch which was merged in HEAD enables creating new GDB commands in Python, so you can write new commands to do some frame tricks too!
If you’d like to know more about the Python scripting work in GDB, I suggest you read the series of blog posts from Tom Tromey on this subject. It’ll give you a pretty good idea of what we have in the Python branch, and the direction we’re heading. Just keep in mind that some method names and syntax changed since he wrote that. Refer to the GDB manual in the Python branch (“make gdb.pdf” in gdb/doc/) or the example scripts (also in the Python branch, in gdb/python/lib/gdb/) for up-to-date details.
Read Full Post »