# 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.

```python
breakpoint()  # Added in Python 3.7. Calls sys.breakpointhook(), which defaults to pdb.set_trace().
```

```bash
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

- [pdb — The Python Debugger](https://docs.python.org/3/library/pdb.html) (official docs)
- [Built-in `breakpoint()` function](https://docs.python.org/3/library/functions.html#breakpoint)
- [`PYTHONBREAKPOINT` environment variable](https://docs.python.org/3/using/cmdline.html#envvar-PYTHONBREAKPOINT)
- [Python Debugging With Pdb](https://realpython.com/python-debugging-pdb/) (Real Python)
