2013-03-16

I learned to program in C, and I got used to GDB’s multi-frame navigation. When GDB prints the stack, it numbers the frames. frame [n] tells GDB to go directly to frame n . Its up [n] and down [n] commands move up and down the stack by `n’ frames.

... Breakpoint 1, zero () at framenav.c:4 (gdb) where #0 zero () at framenav.c:4 #1 0x0000000100000de8 in one () at framenav.c:9 #2 0x0000000100000e08 in two () at framenav.c:14 #3 0x0000000100000e28 in three () at framenav.c:19 #4 0x0000000100000e44 in main (argc=1, argv=0x7fff5fbff750) at framenav.c:23 (gdb) frame 3 #3 0x0000000100000e28 in three () at framenav.c:19 (gdb) frame 1 #1 0x0000000100000de8 in one () at framenav.c:9 (gdb) up 3 #4 0x0000000100000e44 in main (argc=1, argv=0x7fff5fbff750) at framenav.c:23 (gdb) down 4 #0 zero () at framenav.c:4

For as long as I’ve used Python’s debugger pdb, I’ve wondered why its up and down commands can only move one frame at a time. Navigating a deep stack using pdb is pretty tedious. You can use aliases to move more than one frame at a time, but even then, you have the burden of counting frames.

Here’s an alternative, implemented as a patch for pdb++, a drop-in pdb replacement.

With the patch, pdb++’s w numbers frames, frame [n] moves directly to frame n , up [n] moves up n frames, and down [n] moves down n frames.

(Pdb++) w [0] /usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/bdb.py(387)run() -> exec cmd in globals, locals [1] <string>(1)<module>() [2] /Users/mlm/tmp/framenav.py(11)<module>() -> two() [3] /Users/mlm/tmp/framenav.py(8)two() -> three() [4] /Users/mlm/tmp/framenav.py(5)three() -> four() [5] > /Users/mlm/tmp/framenav.py(2)four() -> pass (Pdb++) frame 4 [4] > /Users/mlm/tmp/framenav.py(5)three() -> four() (Pdb++) up 3 [1] > <string>(1)<module>() (Pdb++) down 4 [5] > /Users/mlm/tmp/framenav.py(2)four() -> pass