Skip to content

Driving GDB

One goal I have for integrating Python scripting into gdb is to be able to fully control gdb from Python. I’ve made a few steps toward this recently. Today I can do:

#! /home/tromey/gnu/python-gdb/build/gdb/gdb --python

import sys, gdb
from hack import inferior

child = inferior(sys.argv)
if not child.run():
    gdb.execute("bt 5")
    gdb.cli()

This is a short script that is marked executable. With this, I can invoke “stop-if-broken my-program arguments“. This will run the program; if it dies for some reason, it will print a stack trace and bring up the gdb command line. Otherwise, it exits.

I like to think you can already see the future of gdb here, though. And although this is pretty young, you can easily extend it a bit — for instance, you could add breakpoints between creating the inferior and starting it. Still, don’t be totally fooled; this is still a toy and there is a lot to do on the gdb side.

The “hack” stuff is because I have no clue about intelligently managing Python packages. I’m looking for a good guide here. What I really want to do, I think, is have classes like Inferior, Breakpoint, etc, directly in the gdb namespace, but I don’t want everything in one huge file. Or is this javathink? Writing “import gdb.inferior.Inferior” feels weird. (If you’re going to give me advice — which I really want — there is an added wrinkle, which is that the gdb module is created directly in the C code in gdb.)

4 Comments

  1. Evan Jones wrote:

    I guess I’m confused here: the gdb module is created in the C code, and the Inferior and Breakpoint classes are implemented in C or in Python? If they are implemented in C, then it is pretty straightforward: PyModule_AddObject adds classes to a module, as shown in the tutorial:

    http://docs.python.org/ext/dnt-basics.html

    If you want the Inferior, etc to be implemented in *Python*, but live in the “gdb” package which is created in C, you have exceeded my Python/C knowledge. I suspect you might be able to call the appropriate Python methods from the gdb module’s init function, which could then in turn call PyModule_AddObject? Or do the C equivalent of:

    # Load the inferior.py file
    import inferior
    # Put Inferior into the gdb namespace
    Inferior = inferior.Inferior

    Good luck.

    Tuesday, August 12, 2008 at 10:55 am | Permalink
  2. tom wrote:

    Some classes are in C; those we just add to the “gdb” module. At some point we’ll start shipping a library of python code as well, though.

    Mostly I want to be able to have a single class per file, to make hacking simpler and to keep startup time low. But, suppose I put “class Inferior” in gdb/inferior.py… having everybody write “import gdb.inferior.Inferior” seems redundant; I’d really just rather “import gdb.Inferior”.

    Is that weird? It is also important to me that the result feel pythonic. I’m just not a python expert so I don’t know what exactly that means :-)

    Anyway, thanks for your idea, I will play with something like that.

    Wednesday, August 13, 2008 at 12:20 am | Permalink
  3. sebastien wrote:

    there is always the hack of pulling in content of your .py files from inside the __init__.py of your module:
    gdb
    __init__.py
    foo.py

    if foo.py contains a class Foo, you can write in the __init__.py file:

    from foo import Foo

    see the multiprocessing module for example:
    http://svn.python.org/view/python/trunk/Lib/multiprocessing/__init__.py?rev=64257&view=auto

    cheers,
    sebastien.

    Wednesday, August 13, 2008 at 8:17 pm | Permalink
  4. zw wrote:

    I would create a directory called gdb and put __init__.py file inside. That would create the public interface for the gdb module. Your original gdb (implemented in C) would be called _gdb (modeled along the lines of _socket or _ssl or _ctypes in the standard python distribution). Within the __init__.py there can be some combination of “from _gdb import *” and __all__ definition to create the proper outside interface.

    from _gdb import *
    from inferior import Inferior
    __all__ = ['somesymbol_from_gdb', 'Inferior', ...]

    … could do what you want. With __all__ you can prepare what is seen when you do “from gdb import *”.

    Wednesday, August 13, 2008 at 8:52 pm | Permalink

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*