Sunday, November 17, 2024
Google search engine
HomeLanguagesDebugging in Python with Pdb

Debugging in Python with Pdb

The PDB module in Python gives us gigantic highlights for compelling debugging of Python code. This incorporates:  

  • Pausing of the program
  • Looking at the execution of each line of code
  • Checking the values of variables

This module is already installed with installing of python. So, we only need to import it into our code to use its functionality. Before that we must know some concepts which are mentioned below:

  1. To import we simply use import pdb in our code.
  2. For debugging, we will use pdb.set_trace() method. Now, in Python 3.7 breakpoint() method is also available for this.
  3. We run this on Python idle terminal (you can use any ide terminal to run).

Let’s begin with a simple example consisting of some lines of code. 

Example:

Python3




# importing pdb
import pdb
  
# make a simple function to debug
def fxn(n):
    for i in range(n):
        print("Hello! ", i+1)
  
  
# starting point to debug
pdb.set_trace()
fxn(5)


Output:

Here, we can see that when the function call is done then pdb executes and ask for the next command. We can use some commands here like 

c -> continue execution

q -> quit the debugger/execution

n -> step to next line within the same function

s -> step to next line in this function or a called function

To know more about different commands you can type help and get the required information.

Now, we will execute our program further with the help of the n command.

In a similar way, we can use the breakpoint() method (which doesn’t need to import pdb).

Python3




# a simple function
def fxn(n):
    for i in range(n):
        print("Hello! ", i+1)
  
  
# using breakpoint
breakpoint()
fxn(5)


Output:

Features provided by PDB Debugging

1. Printing Variables or expressions

When utilizing the print order p, you’re passing an articulation to be assessed by Python. On the off chance that you pass a variable name, pdb prints its present worth. Notwithstanding, you can do considerably more to examine the condition of your running application.

An application of PDB debugging in the recursion to check variables

In this example, we will define a recursive function with pdb trace and check the values of variables at each recursive call. To the print the value of variable, we will use a simple print keyword with the variable name.

Python3




# importing pdb
import pdb
  
# define recursive function
def rec_fxn(r):
    if r > 0:
  
        # set trace
        pdb.set_trace()
        rec_fxn(r//2)
    else:
        print("recursion stops")
    return
  
# set trace at start
pdb.set_trace()
rec_fxn(5)


Output:

An Example to check expressions

This example is similar to the above example, that prints the values of expressions after their evaluation.

Python3




# importing pdb
import pdb
  
# simple function
def fxn(n):
    l=[]
    for i in range(n):
        l.append(i)
  
    # set trace
    pdb.set_trace()
    return
  
fxn(5)


Output:

2. Moving in code by steps

This is the most important feature provided by pdb. The two main commands are used for this which are given below:

n -> step to next line within the same function

s -> step to next line in this function or a called function

Let’s understand the working of these with the help of an example.

Python3




# importing pdb
import pdb
  
# simple function
def fxn(n):
    l = []
    for i in range(n):
        l.append(i)
    return
  
  
# set trace
pdb.set_trace()
fxn(5)


Output Using n:

Output Using s:

3. Using Breakpoints

This feature helps us to create breakpoints dynamically at a particular line in the source code. Here, in this example, we are creating breakpoint using command b which given below:

b(reak) [ ([filename:]lineno | function) [, condition] ]
        Without argument, list all breaks.

With a line number argument, set a break at this line in the current file.  With a function name, set a break at the first executable line of that function.  If a second argument is present, it is a string specifying an expression that must evaluate to true before the breakpoint is honored.

The line number may be prefixed with a filename and a colon, to specify a breakpoint in another file (probably one that hasn’t been loaded yet).  The file is searched for on sys.path; the .py suffix may be omitted.

Python3




# importing pdb
import pdb
  
# simple function
def fxn(n):
    l = []
      
    for i in range(n):
        l.append(i)
    print(l)
    return
  
  
# set trace
pdb.set_trace()
fxn(5)


Output:

4. Execute code until the specified line

Use unt to proceed with execution like c, however, stop at the following line more noteworthy than the current line. Now and then unt is more helpful and faster to utilize and is actually what you need.

unt(il) [lineno]

Without argument, continue execution until the line with a number greater than the current one is reached.  With a line number, continue execution until a line with a number greater or equal to that is reached.  In both cases, also stop when the current frame returns.

Python3




# importing pdb
import pdb
  
# simple function
def fxn(n):
    
    # set trace
    pdb.set_trace()
    l = []
      
    for i in range(n):
        l.append(i)
    print(l)
    return
  
  
fxn(5)


Output:

5. List the code

Listing Source code is another feature that can be used to track the code with a line number as a list. For this ll command is used.

longlist | ll -> List the whole source code for the current function or frame.

Let’s understand the working of longlist with the help of an example.

Python3




# importing pdb
import pdb
  
# simple function
def fxn(n):
    l=[]
  
    for i in range(n):
        l.append(i)
    return
  
# set trace
pdb.set_trace()
fxn(5)


Output:

6. Displaying Expressions

Like printing articulations with p and pp, you can utilize the order show [expression] to advise pdb to consequently show the estimation of an articulation, on the off chance that it changed, when execution stops. Utilize the order undisplay [expression] to clear a showcase articulation.

display [expression]

Display the value of the expression if it changed, each time execution stops in the current frame. Without expression, list all display expressions for the current frame.

undisplay [expression]

Do not display the expression any more in the current frame. Without expression, clear all display expressions for the current frame.

Python3




# importing pdb
import pdb
  
# simple function
def fxn(n):
    l = []
      
    for i in range(n):
        l.append(i)
      
    # set trace
    pdb.set_trace()
    print(l)
    return
  
  
fxn(5)


Output:

7. Frames up-down

Here, we can play with each trace as a frame, and we can also move from one frame to another.

w(here)

Print a stack trace, with the most recent frame at the bottom. An arrow indicates the “current frame”, which determines the context of most commands.  ‘bt’ is an alias for this command.

u(p) [count]

Move the current frame count (default one) levels up in the stack trace (to an older frame).

d(own) [count]

Move the current frame count (default one) levels down in the stack trace (to a newer frame).

Python3




# importing pdb
import pdb
  
# simple function
def fxn(i):
    print(i)
    return
  
# set trace
pdb.set_trace()
for i in range(5):
    fxn(i)


Output:

RELATED ARTICLES

Most Popular

Recent Comments