So far we’ve concentrated on way to use Python to extend gdb: writing new commands, writing new functions, and customized pretty-printing. In this post I want to look at gdb from a different angle: as a library. I’ve long thought it would be pretty useful to be able to use gdb as a kind of scriptable tool for messing around with running programs, or even just symbol tables and debug info; the Python work enables this.
One word of warning before we begin: we’re starting to get into the work-in-progress parts of python-gdb. If you play around here, don’t be surprised if it is not very polished. And, as always, we’re interested in your feedback; drop us a line on the Archer list.
For historical and technical reasons, it is pretty hard to turn gdb into an actual loadable Python library. This might be nice to do someday; meanwhile we’ve made it possible to invoke gdb as an interpreter: add the “
-P” (or “
--python“) option. Anything after this option will be passed to Python as
sys.argv. For example, try this script:
#!/home/YOURNAME/archer/install/bin/gdb -P print "hello from python"
Ok… so far so good. Now what? How about a little app to print the size of a type?
#!/home/YOURNAME/archer/install/bin/gdb -P import sys import gdb gdb.execute("file " + sys.argv) type = gdb.Type (sys.argv) print "sizeof %s = %d" % (sys.argv, type.sizeof ())
You can script that with gdb today, though the invocation is uglier unless you write a wrapper script. More complicated examples are undeniably better. For instance, you can write a “pahole” clone in Python without much effort.
That invocation of
gdb.execute is a bit ugly. In the near future (I was going to do it last week, but I got sick) we are going to add a new class to represent the process (and eventually processes) being debugged. This class will also expose some events related to the state of the process — e.g., an event will be sent when the process stops due to a signal.
The other unfinished piece in this area is nicer I/O control. The idea here is to defer gdb acquiring the tty until it is really needed. With these two pieces, you could run gdb invisibly in a pipeline and have it bring up the CLI only if something goes wrong.
It will look something like:
#!/home/YOURNAME/archer/install/bin/gdb -P import sys import gdb def on_stop(p): (status, value) = p.status if status != gdb.EXIT: gdb.cli () else: sys.exit (value) process = gdb.Inferior(sys.argv) process.connect ("stop", on_stop) process.run ()
I’ll probably use python-gobject-like
connect calls, unless Python experts speak up and say I should do something different.
The next post will cover a flashier use of Python in gdb. Stay tuned.