Multi-frame navigation in a Python debugger
, Wellesley, MAI 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
Although pdb and pdb++ number Python stack frames the opposite order
that GDB numbers C stack frames, up
and down
move in the same
logical order — opposite numerical order — as their respective GDB
commands. up
moves toward the outermost frame, and down
moves toward
the innermost frame.