Debugging Python programs
There are many IDEs out there that make it a breeze to debug python. But one day you might find yourself in a situtation where you do not have access to this fancy IDE of yours, and you’re trying to debug a program from the interpreter.
In a file named crash.py
, have the following toy function:
def print_list(l):
for it in l:
print l
Now let’s run this with an argument which is not iterable (like an integer):
>>> import crash
>>> crash.print_list(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "crash.py", line 2, in print_list
for it in l:
TypeError: 'int' object is not iterable
>>>
Okay - so it crashes as expected. Let’s debug!
>>> pdb.pm()
> /tmp/crash.py(2)print_list()
-> for it in l:
(Pdb) a
l = 1
(Pdb)
a
shows the local variables - here we clearly see l
is set to 1. But what if we wanted to step through? Well we can’t quite do that once the program has been terminated so let’s re-run it with pdb
from the start.
>>> pdb.run('crash.print_list(1)')
> <string>(1)<module>()
We’re now at the very top of the program. Before continuing, let’s set a breakpoint on the for
statement:
(Pdb) b crash:2
Breakpoint 1 at /tmp/crash.py:2
(Pdb) c
> /tmp/crash.py(2)print_list()
-> for it in l:
(Pdb) print type(l)
<type 'int'>
(Pdb) l
1 def print_list(l):
2 B-> for it in l:
3 print it
[EOF]
We can set we hit the breakpoint (denoted by ‘B’), and we use l
to list the current source. Now that we’re in a debug session, let’s make l
an actual list.
(Pdb) l=[1,2,3,4]
*** Error in argument: '=[1,2,3,4]'
Right that was cheeky - pdb
interprets l
as the list command. We need to explicitly tell pdb
it’s a python command, and we do that by prefixing it with !
. And we continue execution
(Pdb) !l=[1,2,3,4]
(Pdb) c
1
> /tmp/crash.py(2)print_list()
-> for it in l:
(Pdb)
Press c
to continue stepping through this, or cl
to clear all breakpoints and r
to resume execution.
This only touches the surface and there’s much more pdb
can do. We’ve been spoilt by GUI-based debuggers and you’ll probably never need the above. But one day it just might get you out of an undesireable situation ^_^