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
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.
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.
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.
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 *”.