Debugging in Python using pdb Library
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+' ' +str2if __name__ == "__main__":
var1 = "hello"
var2 = "world"
import pdb; pdb.set_trace()
out = concate_str(var1, var2)
print(out)
p var1
evaluates the expression in the current context and print its value.
pp var2
pretty print the expression.
q
to quit the 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.
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.
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+' ' +str2if __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.
Or breakpoint can also be set with the command b
and directly to the function.
cl
or clear
the command will clear all the soft breakpoint that you set for current execution. (Note: Hard breakpoint still exist)
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+' ' +str2if __name__ == "__main__":
var1 = "hello"
var2 = "world"
import pdb; pdb.set_trace()
out = concate_str(var1, var2)
pdb.set_trace()
print(out)
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.