Debugging

Debugging is the process of systematically finding and identifying errors in your program.

printf-style debugging

One of the simplest approaches you can take to debugging a program is to litter your source code with print statements (printf in C, cout in C++, print in Python...). You can then run your program and follow the state of execution as your program proceeds. Although this method can be useful to quickly identify big problems in your code, it requires modifying your source code (and then recompiling, if necessary) to change what information is being logged.

Note that you can replace printf-style debugging with a formal logging system such as the logging module in Python.

Using a debugger

Specialized tools called debuggers have been developed for almost all languages. These programs are able to inspect the state of the running program, including pausing the execution and inspecting the current values of program variables.

pdb

The pdb module for Python provides a command-line debugger. The file linked_list.py contains a (flawed) implementation of a doubly-linked list. The file pdb_linked_list.py contains some code that imports the linked list module, creates a linked list, and runs some commands. We will attach a debugger to this program to be able to analyze the program at runtime.

The following is a pdb session where we set a breakpoint at the last statement in the pop method, and tell the debugger to print out a string representation of the linked list each time we encounter this breakpoint.

$ python3 -m pdb pdb_linked_list.py
> ~/pdb_linked_list.py(1)<module>()
-> import linked_list
(Pdb) b linked_list.py:47
Breakpoint 1 at ~/linked_list.py:47
(Pdb) commands 1
(com) p str(self)
(com) end
(Pdb) c
'[1, 2]'
> ~/linked_list.py(47)pop()
-> return z.value
(Pdb) c
'[1]'
> ~/linked_list.py(47)pop()
-> return z.value
(Pdb) c
'[1]'
> ~/linked_list.py(47)pop()
-> return z.value
(Pdb) c
The program finished and will be restarted
> ~/pdb_linked_list.py(1)<module>()
-> import linked_list
(Pdb)

The actual commands entered are as follows:

b linked_list.py:47
commands 1
p str(self)
end
c
c
c
c

Once the program finishes, the debugger automatically restarts it for further analysis, keeping all defined breakpoints.