Debugging in Python using pdb Library

Pritesh Gohil
5 min readSep 29, 2020
Copyright: Pritesh Gohil

The aim of this article is to get user familiar and confident about debugging python code in terminal using debugger library pdb . The first question is, why do we need debugging? We know that errors (sometimes ‘bugs’) in software code can cause it to behave unexpectedly or crash. Debugging is the process of detecting and removing existing and potential errors or bugs. To prevent incorrect operation of a software or system, debugging is used to find and resolve bugs or defects. Then next question is, why exactly pdb? Usually debugging is possible with IDEs (Integrated Development Environment) such as PyCharm. However, we might not have access to debugger always and we are in hurry to fix some script or code, then command-line debugging is a lifesaver.

Getting started

Type following just before the line you want to put a breakpoint

import pdb; pdb.set_trace()

Or python -m pdb pdb_example.py to start debugging from __main__.

Then normally run your python code in the terminal. Code execution will stop at the line where we set_trace. Now let say there is a variable var1 and you want to inspect that variable, then type p VARIABLE_NAME . See below example for more clear understanding

def concate_str(str1, str2):
print("first word is: {}".format(str1))
print("second word is: {}".format(str2))
return str1+' ' +str2
if __name__ == "__main__":
var1 = "hello"
var2 = "world"
import pdb; pdb.set_trace()
out = concate_str(var1, var2)
print(out)
Run pbd_example.py script in terminal

p var1evaluates the expression in the current context and print its value.

pp var2pretty print the expression.

q to quit the debugger.

Debugging by printing variable. ‘q + Enter’ to exit debugger.

Printing expressions

To list out next 11 lines of code around the current line, type l . Typing again l will list out next 11 lines of code. If your program ends before 11 lines then you will see [EOF] (End Of Line) message.

Pressing Enter at any time in debugging session will tell pdb to use the last command that was entered i.e. l in our case.

l to print next 11 lines of code around the current line and function.

l . to go back to the debug point

ll to list all source code for the current function or frame.

Executing command l, Enter, l ., and ll in debugging mode

Stepping through code

Once you are in debug mode and then python program will stop execution at particular trace_point(). After inspecting the variables, we often want to step on the next line of code to see the behaviour of the code. Following are the options for that.

s or next will execute the current line and stop at the next line of code. Next line can be function it is calling or next line of the current function. Difference between s and next is rarely noticeable. s will allow stepping into the python library functions, whereas next will not step into the library functions.

until will try to execute the current line in the current file and stop at next line in the same file. This cmd can be used to skip loops or any function calls. In the case of s and next , it will go to the function or loop in the next file and may end up with an unnecessary step in debugging.

a to print the argument list of the current function

pdb can step back to the previous line using jump command but unfortunately executed line can not be reversed. For this reason, epdb is developed.

Continuing execution

To continue the execution after the breakpoint just type c . If there is another breakpoint in the program, execution will stop there, otherwise, it will execute normally.

continue execution with command ‘c’

Working with breakpoints

There are needs to set multiple breakpoints and we can do by writing pdb.set_trace() as given in the following example. This breakpoint is called hard breakpoint and can not be cleared during execution.

def concate_str(str1, str2):
print("first word is: {}".format(str1))
print("second word is: {}".format(str2))
return str1+' ' +str2
if __name__ == "__main__":
var1 = "hello"
var2 = "world"
import pdb; pdb.set_trace()
out = concate_str(var1, var2)
pdb.set_trace()
print(out)

Another way to do it is by following python syntax break <program_file>:<line_number>. This breakpoint is soft breakpoint and can be removed during execution. Run the original python script with only one set_trace() and type following in debug mode.

Breakpoint using ‘break’ command

Or breakpoint can also be set with the command b and directly to the function.

Breakpoint to function using command ‘b’

cl or clear the command will clear all the soft breakpoint that you set for current execution. (Note: Hard breakpoint still exist)

Clear all the soft breakpoints

Demonstration for hard breakpoint and clear command

def concate_str(str1, str2):
print("first word is: {}".format(str1))
print("second word is: {}".format(str2))
return str1+' ' +str2
if __name__ == "__main__":
var1 = "hello"
var2 = "world"
import pdb; pdb.set_trace()
out = concate_str(var1, var2)
pdb.set_trace()
print(out)
‘cl’ command clears the only soft breakpoint

Summary

If you find this article useful, let me know by clapping it or with your comment. If you have any questions, write it in the comment.

References

[1] https://docs.python.org/3/library/pdb.html

--

--