Of course pdb has already got functions to start a debugger in the middle of your program, most notably
pdb.set_trace(). This however requires you to know where you want to start debugging, it also means you can't leave it in for production code.
But I've always been envious of what I can do with GDB: just interrupt a running program and start to poke around with a debugger. This can be handy in some situations, e.g. you're stuck in a loop and want to investigate. And today it suddenly occurred to me: just register a signal handler that sets the trace function! Here the proof of concept code:
import os import signal import sys import time def handle_pdb(sig, frame): import pdb pdb.Pdb().set_trace(frame) def loop(): while True: x = 'foo' time.sleep(0.2) if __name__ == '__main__': signal.signal(signal.SIGUSR1, handle_pdb) print(os.getpid()) loop()
Now I can send
SIGUSR1 to the running application and get a debugger. Lovely!
I imagine you could spice this up by using Winpdb to allow remote debugging in case your application is no longer attached to a terminal. And the other problem the above code has is that it can't seem to resume the program after pdb got invoked, after exiting pdb you just get a traceback and are done (but since this is only
bdb raising the
bdb.BdbQuit exception I guess this could be solved in a few ways). The last immediate issue is running this on Windows, I don't know much about Windows but I know they don't have signals so I'm not sure how you could do this there.