# Introduction to the PDB Python Debugging Tool

Professor Norm Matloff
University of California, Davis
(author of The Art of Debugging, NSP, 2008 )

## Overview:

PDB is Python's built-in debugging tool. While it is not very sophisticated (see WinPDB and Emacs for nice programs), it does the job, and is certainly fine for debugging small programs.

Nothing to install--it comes with Python.

## The Principle of Confirmation:

The way that a debugging tool helps you find your bugs is that it makes it easy to apply what I call the Principle of Confirmation:

Keep confirming that what you are "sure" is true, really is true. Eventually you'll find something that doesn't confirm, and then you'll probably have pinpointing the location of a bug.

Are you "sure" that your variable w has the value 88 on line 20? Confirm it! Are you "sure" that in a certain if/else statement, the code takes the else branch in a certain situation? Confirm it! A debugging tool makes this easy to do, by allowing you to execute your program line by line, querying the values of variables along the way.

## Example program:

Here is code to do binary search: One has an array (Python list) that is always in sorted order, small to large. We wish to insert a new value, and the code is suppose to tell us the index at which to insert it.

For example, say we wish to insert 6 into [5,12,13]. Then the insertion point would be 1, since the 6 would go just before 12, which has index 1 in the list. The insertion point for 1 would be 0, since 1 would go before the 5.

Here is the buggy code:

```def findinspt(x,xnew):  # returns insertion point of xnew in x
n = len(x)
lo = 0
hi = n-1
while True:
mid = (lo + hi) / 2
if xnew > x[mid]: lo = mid + 1
else: hi = mid
if xnew == x[mid]: return mid

def main():
y = [5,12,13]
print findinspt(y,3)

if __name__ == '__main__': main()
```

Don't worry about that last line for now; just make sure to include it, and make sure to have a function named main() at which execution is to begin.

## Sample debugging session:

Let's try running the program, which I named bsrch.py. I opened a terminal window, and did the following (this was on Linux, but would be the same elsewhere:

```% python bsrch.py
Traceback (most recent call last):
File "bsrch.py", line 16, in
if __name__ == '__main__': main()
File "bsrch.py", line 14, in main
print findinspt(y,3)
File "bsrch.py", line 8, in findinspt
if xnew > x[mid]: lo = mid + 1
KeyboardInterrupt
```

The program went into an apparent infinite loop, so I killed it using ctrl-c. I then reran it under PDB:

```python -m pdb bsrch.py
> /home/nm/145/bsrch.py(2)()
-> def findinspt(x,xnew):  # returns insertion point of xnew in x
(Pdb) l
1
2  -> def findinspt(x,xnew):  # returns insertion point of xnew in x
3        n = len(x)
4        lo = 0
5        hi = n-1
6        while True:
7           mid = (lo + hi) / 2
8           if xnew > x[mid]: lo = mid + 1
9           else: hi = mid
10           if xnew == x[mid]: return mid
11
```

PDB gave me its (pdb) prompt, and to take a look around, I gave the l (list code) command. PDB responded by showing me a few lines of code. I could have hit l again to see more, and just hit the Enter key (which repeats the last command).

I decided to see a breakpoint at line 7, which tells PDB to pause execution of the program whenever it hits that line. I then hit c (continue) to resume execution, and sure enough, PDB paused there:

```(Pdb) b 7
Breakpoint 1 at /home/nm/145/bsrch.py:7
(Pdb) c
> /home/nm/145/bsrch.py(7)findinspt()
-> mid = (lo + hi) / 2
```

I could then "take a look around," querying the values of variables:

```(Pdb) lo
0
(Pdb) hi
2
(Pdb) x
[5, 12, 13]
(Pdb) print n
3
```

Note that I could not just type n to display that variable, since n is a PDB command to go to the next line.