Skip to content

pdb: Python's Built-in Debugger

pdb is Python’s interactive source debugger, distributed as a module in the standard library. It supports setting breakpoints, single-stepping at the source-line level, inspecting and modifying variables in any stack frame, and post-mortem analysis of an unhandled exception. The interface is line-oriented and runs in any terminal with no external dependencies.

When to use pdb

Use pdb when a problem can be reproduced locally and adding a print statement is not enough. Drop a breakpoint() call at the line of interest, run the program, and inspect state interactively. For a crash that has already happened, run the script with python -m pdb -c continue script.py to land in post-mortem at the offending frame. pdb pauses the entire process, so it is not appropriate for debugging long-running production services; reach for logging or a sampling profiler instead.

Invocation

The three common entry points are an in-source breakpoint, running a script under pdb, and post-mortem analysis.

breakpoint()  # Added in Python 3.7. Calls sys.breakpointhook(), which defaults to pdb.set_trace().
python -m pdb script.py              # run a script under the debugger from the start
python -m pdb -c continue script.py  # run normally; only break on uncaught exception
python -m pdb -m mypackage.cli       # run a module under the debugger (added in 3.7)
python -m pdb -p PID                 # attach to a running process (added in 3.14)

PYTHONBREAKPOINT=0 disables every breakpoint() call in the process, which is useful for production deployments that should never enter an interactive debugger. Setting it to a dotted path (PYTHONBREAKPOINT=IPython.terminal.debugger.set_trace) routes breakpoint() to a different debugger.

For programmatic post-mortem analysis, pdb.pm() enters the debugger on the most recent unhandled exception, and pdb.post_mortem(tb_or_exc) enters on a specific traceback or exception object (exception-object support added in Python 3.13).

Commands

Program flow

  • s (step): execute the next line, descending into any called function
  • n (next): execute the next line, stepping over calls
  • unt (until) [lineno]: continue past the current line, or until the given line
  • r (return): continue until the current frame returns
  • c (continue): resume execution until the next breakpoint or program end
  • j lineno (jump): set the next line to execute, skipping or replaying lines
  • q (quit): exit the debugger and abort the program

Stack navigation

  • w (where): print the stack trace, current frame at the bottom
  • u (up) [count]: move toward callers
  • d (down) [count]: move toward callees
  • a (args): print the current frame’s arguments
  • retval: print the return value of the most recently returned function

Breakpoints

  • b [filename:]lineno (break): set a breakpoint at a line
  • b function: break on entry to a function
  • tbreak: set a temporary breakpoint, cleared after first hit
  • cl [bpnumber ...] (clear): remove breakpoints
  • disable bpnumber / enable bpnumber: toggle without removing
  • condition bpnumber expr: only stop when expr evaluates true
  • ignore bpnumber count: skip the next count hits
  • commands [bpnumber]: define commands to run automatically when the breakpoint is hit

Inspection

  • p expr: evaluate and print
  • pp expr: pretty-print
  • whatis expr: print the type
  • source expr: show the source of a class or function (added in 3.2)
  • display [expr]: re-print expr after every step (added in 3.2)
  • undisplay [expr]: stop tracking a display
  • l (list): show source around the current line
  • ll (longlist): show the full current function (added in 3.2)
  • interact: drop into a Python REPL with the current frame’s locals (added in 3.2)

Aliases and raw Python

  • alias name command [%1 %2 ...]: define a textual alias for a command sequence
  • unalias name: remove an alias
  • ! statement: execute an arbitrary Python statement in the current frame’s namespace

Configuration

pdb reads ~/.pdbrc from the user’s home directory and ./.pdbrc from the current working directory at startup. Both files are executed line-by-line as if typed at the debugger prompt; empty lines and lines beginning with # are ignored. The home file is read first, and the cwd file overrides it where they collide. Since Python 3.11, .pdbrc is read with UTF-8 encoding (previously the system locale).

.pdbrc is not Python source. It accepts pdb commands such as alias, b, c, and display. There is no syntax for multi-line aliases; chain statements with ; if needed, and remember that any names assigned during an alias leak into the debuggee’s frame.

The two example aliases from the official documentation print instance variables:

# print instance vars (usage: pi classInst)
alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}")
# print instance vars in self
alias ps pi self

Since Python 3.2, .pdbrc may contain commands that resume execution, such as continue or next; earlier versions silently ignored them.

Limitations

  • Line-oriented interface with no built-in syntax highlighting or call-graph view.
  • Pauses the entire process, so it is not suitable for production debugging of long-running services.
  • No first-class remote debugging in the standard library; reach for remote-pdb, web-pdb, or debugpy (the engine VS Code’s Python extension uses) for that.

Learn More

Last updated on