Python stack in GDB

I’m sure everyone already knows about this, but it’s such a nice feature I’ll post it anyway.

There’s a set of macros for gdb, described in a comment on this page, that will let you attach to a running python program using gdb and inspect its python call stack and python objects using the familiar interface of gdb.   I’m a complete stranger to python and couldn’t figure out how to enable the python debugger, and it would get me lost even if I managed to enable it. Additionally I was trying to find out when and why a python program uses a particular syscall and I’m not sure the python debugger can help with this.  For the record that python program blocks all signals so I couldn’t just send it a signal and have it print the stack.

I’m wondering if you can do the same thing with Java, and who’ll be the first to implement the gdb macros.  I’ve not coded java for years but it makes me want to have a look at it again considering there’s source code for it now (I just wish I had the time). How about swi-prolog?

Practical note: For this to work you will need to rebuild python with debug information in. If you’re on Gentoo, whose default package manager uses python, and if you still have python2.4 installed, if you screw up your python2.5 installation, you can revive emerge by running it implicitly with python2.4 (python2.4 /usr/bin/emerge blah blah).  To rebuild python with custom options, edit /usr/portage/dev-lang/python/python-2.5.2-r8.ebuild to add –with-pydebug, and run ebuild /usr/portage/dev-lang/python/python-2.5.2-r8.ebuild digest unpack, then edit /var/tmp/portage/dev-lang/python-2.5.2-r8/work/Python-2.5.2/Objects/unicodeobject.c to remove the assert on line 372, which seems to be a typo, and then ebuild /usr/portage/dev-lang/python/python-2.5.2-r8.ebuild compile install qmerge to let it finish.  You may need to re-emerge some of the packages that have installed into /usr/lib/python2.5/site-packages) for your program to work again.

Advertisements

3 Responses to “Python stack in GDB”

  1. tahorg Says:

    import pdb and just put pdb.set_trace() where you want to stop. The interface is gdb-like, you won’t get lost :)

  2. balrog Says:

    I tried to use pdb but I couldn’t get it to stop, probably pebkac (do you need to be running from inside python interactive mode?), but the real issue was:

    Strace’ing the python program, I saw it use a particular syscall and wanted to know where that was happening in the python code. I don’t think pdb would let you set a breakpoint at a random memory address given by strace? That’s where gdb comes helpful.

  3. Andrew Farrell Says:

    no, you just need to paste the following line somewhere in the code

    import pdb;pdb.set_trace()

    example

    def spam():
    a = 34
    import pdb;pdb.set_trace()
    b = 5
    return a + b

    and if spam() gets called, and the interpereter will hit the second line and you’ll be popped into pdb.

    If that isn’t happening, then you should try inserting the line
    assert False
    before it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: