Today I used the Python support in gdb to do real work. Until now I’ve just been playing around, adding functionality that looked fun.
My application was something I’ve wanted to be able to do in gdb for a long, long time: set a breakpoint in one function, but have the breakpoint be conditional on the caller. In my case, I’m debugging the compile server, and I want to examine calls to
c_parser_lookup_callback which pass a complicated test (that is, the breakpoint is in the true branch of an
if statement); but only calls originating in
declspecs_add_type are interesting.
Roland taught me that you can fake this in plain gdb by using convenience variables and breakpoint commands. However, it is rather painful to get this right, as you have to remember to reset the convenience variable in some cases (in my case, if we reach the outer breakpoint but not the inner one).
With the Python support, this kind of thing is easy. First I define a Python function to do a little work:
(gdb) python Type python script End with a line saying just "end". >def check(): > frame = gdb.current_frame().get_prev() > return frame.get_name() == "declspecs_add_type" >end
As you can see this just checks the parent frame’s function name.
Now, I make the breakpoint conditional on this function’s value:
(gdb) cond 1 $(check())
That’s all there is to it!
I suppose I could have written this as a one-liner, like:
(gdb) cond 1 $(gdb.current_frame().get_prev().get_name() == "declspecs_add_type")
Both of the above formulations still seem a little clunky to me. But, it is still early days for the Python integration; I think we’ll find some nice ways to simplify common tasks.
What’s your missing feature?