pdb implements an interactive debugging environment for Python programs. It includes features to pause a program, look at the values of variables, and watch program execution step-by-step, so you can understand what the program actually does and find bugs in the logic.

Here the incorrect attribute name on line 14 triggers an AttributeError exception, causing execution to stop. pm() looks for the active traceback and starts the debugger at the point in the call stack where the exception occurred.

set_trace() is just a Python function, so it can be called at any point in a program. This makes it possible to enter the debugger based on conditions inside the program, including from an exception handler or via a specific branch of a control statement.

Line 17 of the sample script triggers the debugger at that point in execution, pausing it on line 18.

Both of the previous examples start the debugger at the beginning of a program. For a long-running process where the problem appears much later in the program execution, it will be more convenient to start the debugger from inside the program using set_trace() .

The argument to run() is a string expression that can be evaluated by the Python interpreter. The debugger will parse it, then pause execution just before the first expression evaluates. The debugger commands described here can be used to navigate and control the execution.

Many Python developers work with the interactive interpreter while developing early versions of modules because it lets them experiment more iteratively without the save/run/repeat cycle needed when creating standalone scripts. To run the debugger from within an interactive interpreter, use run() or runeval() .

Normally pdb includes the full path to each module in the output when printing a filename. In order to maintain clear examples, the path in the sample output in this section has been replaced with ellipsis ( ... ).

Running the debugger from the command line causes it to load the source file and stop execution on the first statement it finds. In this case, it stops before evaluating the definition of the class MyObj on line 8.

The most straightforward way to use the debugger is to run it from the command line, giving it the program as input so it knows what to run.

The first step to using pdb is causing the interpreter to enter the debugger at the right time. There are a few different ways to do that, depending on the starting conditions and what is being debugged.

Controlling the Debugger¶

The interface for the debugger is a small command language that lets you move around the call stack, examine and change the values of variables, and control how the debugger executes the program. The interactive debugger uses readline to accept commands, and supports tab completion for commands, filenames, and function names. Entering a blank line re-runs the previous command again, unless it was a list operation.

Navigating the Execution Stack¶ At any point while the debugger is running use where (abbreviated w ) to find out exactly what line is being executed and where on the call stack the program is. In this case, the module pdb_set_trace.py line 18 in the go() method. $ python3 pdb_set_trace.py > .../pdb_set_trace.py(18)go() -> print(i) (Pdb) where .../pdb_set_trace.py(22)<module>() -> MyObj(5).go() > .../pdb_set_trace.py(18)go() -> print(i) (Pdb) To add more context around the current location, use list ( l ). (Pdb) l 13 self.count = num_loops 14 15 def go(self): 16 for i in range(self.count): 17 pdb.set_trace() 18 -> print(i) 19 return 20 21 if __name__ == '__main__': 22 MyObj(5).go() [EOF] (Pdb) The default is to list 11 lines around the current line (five before and five after). Using list with a single numerical argument lists 11 lines around that line instead of the current line. (Pdb) list 14 9 10 class MyObj(object): 11 12 def __init__(self, num_loops): 13 self.count = num_loops 14 15 def go(self): 16 for i in range(self.count): 17 pdb.set_trace() 18 -> print(i) 19 return If list receives two arguments, it interprets them as the first and last lines to include in its output. (Pdb) list 7, 19 7 import pdb 8 9 10 class MyObj(object): 11 12 def __init__(self, num_loops): 13 self.count = num_loops 14 15 def go(self): 16 for i in range(self.count): 17 pdb.set_trace() 18 -> print(i) 19 return The longlist ( ll ) command prints the source for the current function or frame, without having to determine the line numbers in advance. The command is “longlist” because for long functions it may produce considerably more output than the default for list . (Pdb) longlist 15 def go(self): 16 for i in range(self.count): 17 pdb.set_trace() 18 -> print(i) 19 return The source command loads and prints the full source for an arbitrary class, function, or module. (Pdb) source MyObj 10 class MyObj: 11 12 def __init__(self, num_loops): 13 self.count = num_loops 14 15 def go(self): 16 for i in range(self.count): 17 pdb.set_trace() 18 print(i) 19 return Move between frames within the current call stack using up and down . up (abbreviated u ) moves towards older frames on the stack. down ( d ) moves towards newer frames. Each time you move up or down the stack, the debugger prints the current location in the same format as produced by where . (Pdb) up > .../pdb_set_trace.py(22)<module>() -> MyObj(5).go() (Pdb) down > .../pdb_set_trace.py(18)go() -> print(i) Pass a numerical argument to either up or down to move that many steps up or down the stack at one time.

Examining Variables on the Stack¶ Each frame on the stack maintains a set of variables, including values local to the function being executed and global state information. pdb provides several ways to examine the contents of those variables. pdb_function_arguments.py ¶ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #!/usr/bin/env python3 # encoding: utf-8 # # Copyright (c) 2010 Doug Hellmann. All rights reserved. # import pdb def recursive_function ( n = 5 , output = 'to be printed' ): if n > 0 : recursive_function ( n - 1 ) else : pdb . set_trace () print ( output ) return if __name__ == '__main__' : recursive_function () The args command (abbreviated a ) prints all of the arguments to the function active in the current frame. This example also uses a recursive function to show what a deeper stack looks like when printed by where . $ python3 pdb_function_arguments.py > .../pdb_function_arguments.py(15)recursive_function() -> print(output) (Pdb) where .../pdb_function_arguments.py(19)<module>() -> recursive_function() .../pdb_function_arguments.py(12)recursive_function() -> recursive_function(n - 1) .../pdb_function_arguments.py(12)recursive_function() -> recursive_function(n - 1) .../pdb_function_arguments.py(12)recursive_function() -> recursive_function(n - 1) .../pdb_function_arguments.py(12)recursive_function() -> recursive_function(n - 1) .../pdb_function_arguments.py(12)recursive_function() -> recursive_function(n - 1) > .../pdb_function_arguments.py(15)recursive_function() -> print(output) (Pdb) args n = 0 output = to be printed (Pdb) up > .../pdb_function_arguments.py(12)recursive_function() -> recursive_function(n - 1) (Pdb) args n = 1 output = to be printed The p command evaluates an expression given as argument and prints the result. Python’s print() function is also available, but it is passed through to the interpreter to be executed rather than running as a command in the debugger. (Pdb) p n 1 (Pdb) print(n) 1 Similarly, prefixing an expression with ! passes it to the Python interpreter to be evaluated. This feature can be used to execute arbitrary Python statements, including modifying variables. This example changes the value of output before letting the debugger continue running the program. The next statement after the call to set_trace() prints the value of output , showing the modified value. $ python3 pdb_function_arguments.py > .../pdb_function_arguments.py(14)recursive_function() -> print(output) (Pdb) !output 'to be printed' (Pdb) !output='changed value' (Pdb) continue changed value For more complicated values such as nested or large data structures, use pp to “pretty print” them. This program reads several lines of text from a file. pdb_pp.py ¶ 1 2 3 4 5 6 7 8 9 10 11 12 #!/usr/bin/env python3 # encoding: utf-8 # # Copyright (c) 2010 Doug Hellmann. All rights reserved. # import pdb with open ( 'lorem.txt' , 'rt' ) as f : lines = f . readlines () pdb . set_trace () Printing the variable lines with p results in output that is difficult to read because it may wrap awkwardly. pp uses pprint to format the value for clean printing. $ python3 pdb_pp.py > .../pdb_pp.py(12)<module>()->None -> pdb.set_trace() (Pdb) p lines ['Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

', 'Donec egestas, enim et consecte tuer ullamcorper, lect us

', 'ligula rutrum leo, a elementum el it tortor eu quam .

'] (Pdb) pp lines ['Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

', 'Donec egestas, enim et consectetuer ullamcorper, lectus

', 'ligula rutrum leo, a elementum elit tortor eu quam.

'] (Pdb) For interactive exploration and experimentation it is possible to drop from the debugger into a standard Python interactive prompt with the globals and locals from the current frame already populated. $ python3 -m pdb pdb_interact.py > .../pdb_interact.py(7)<module>() -> import pdb (Pdb) break 14 Breakpoint 1 at .../pdb_interact.py:14 (Pdb) continue > .../pdb_interact.py(14)f() -> print(l, m, n) (Pdb) p l ['a', 'b'] (Pdb) p m 9 (Pdb) p n 5 (Pdb) interact *interactive* >>> l ['a', 'b'] >>> m 9 >>> n 5 Mutable objects such as lists can be changed from the interactive interpreter. Immutable objects cannot, and names cannot be rebound to new values. >>> l.append('c') >>> m += 7 >>> n = 3 >>> l ['a', 'b', 'c'] >>> m 16 >>> n 3 Use the end-of-file sequence Ctrl-D to exit the interactive prompt and return to the debugger. In this example, the list l has been changed but the values of m and n are not. >>> ^D (Pdb) p l ['a', 'b', 'c'] (Pdb) p m 9 (Pdb) p n 5 (Pdb)