SysTutorials

Python Debugging with pdb: A Step-by-Step Command Guide

· updated April 11, 2026

The built-in pdb module is Python’s equivalent to gdb — a command-line debugger that lets you step through code, set breakpoints, inspect variables, and control execution flow. It’s essential for server-side debugging and situations where IDE graphical debuggers aren’t available.

Starting a pdb Session

Run a script through pdb directly:

python -m pdb prog.py arg1 arg2

Or insert a breakpoint within your code:

def my_function():
    x = 10
    breakpoint()  # execution pauses here
    return x * 2

The breakpoint() call (Python 3.7+) is the modern standard. Older code uses import pdb; pdb.set_trace(), which still works but is less readable.

Essential Commands

Type help at the pdb prompt to list all commands. Here are the ones you’ll use constantly:

Command Shortcut Purpose
next n Execute current line without entering functions
step s Execute current line, step into function calls
continue c Resume execution until next breakpoint or exit
break <lineno> b <lineno> Set breakpoint at specified line number
break <funcname> b <funcname> Set breakpoint at function entry
list l Display source code around current position
print <var> p <var> Print variable value
pp <var> pp <var> Pretty-print complex objects (dicts, lists)
where w Show full stack trace
up u Move up one frame in the stack
down d Move down one frame in the stack
return r Execute until current function returns
until <lineno> unt <lineno> Execute until reaching a specific line
whatis <var> — Display variable type
condition <bp> <expr> — Break only when expression evaluates true
commands <bp> — Attach commands to run automatically at breakpoint

Working Through a Practical Example

Consider this function with a logic issue:

def process_data(items):
    result = []
    for item in items:
        value = item * 2
        result.append(value)
    return result

process_data([1, 2, 3])

Run it with pdb:

$ python -m pdb script.py
> /path/to/script.py(1)<module>()
-> def process_data(items):
(Pdb)

Set a breakpoint at line 4 (the calculation) and continue:

(Pdb) b 4
Breakpoint 1 at /path/to/script.py:4
(Pdb) c
> /path/to/script.py(4)process_data()
-> value = item * 2

Inspect variables at this point:

(Pdb) p item
1
(Pdb) p result
[]
(Pdb) p value
NameError: name 'value' is not defined

The variable value doesn’t exist yet because we haven’t executed the assignment. Step forward:

(Pdb) n
> /path/to/script.py(5)process_data()
-> result.append(value)
(Pdb) p value
2

Continue stepping to see the entire first iteration complete:

(Pdb) n
> /path/to/script.py(3)process_data()
-> for item in items:
(Pdb) p result
[2]

Using Conditional Breakpoints

Instead of pausing on every iteration, break only when a condition is true:

(Pdb) b 4, item > 1
Breakpoint 1 at /path/to/script.py:4
(Pdb) c

Now execution pauses only when item exceeds 1. This saves time when debugging loops over large datasets.

Post-mortem Debugging

Debug an exception after it crashes by catching it and entering pdb at the failure point:

import pdb
import traceback

try:
    some_function()
except Exception:
    traceback.print_exc()
    pdb.post_mortem()

This drops you into pdb at the exact location where the exception occurred, with the full stack intact. You can inspect variables, move up and down the stack with up/down, and understand what went wrong.

Alternatively, run a script and let pdb handle uncaught exceptions automatically:

python -m pdb -c continue prog.py

Enhancing pdb with pdbpp

The standard pdb is functional but minimal. For a significantly better experience, install pdbpp:

pip install pdbpp

pdbpp provides:

Once installed, it activates automatically with no additional configuration needed.

Automating Debugging Tasks

You can automate repetitive debugging steps using command scripts. Create a file with pdb commands:

b myfunction
commands 1
p var1
p var2
p var3
continue
end
c

Then run pdb with the script:

python -m pdb -c "source /path/to/commands.txt" prog.py

Remote and Headless Debugging

On servers without graphical access, pdb is your primary tool. Connect via SSH and debug normally:

ssh user@server
python -m pdb /path/to/script.py

For long-running processes, add breakpoints in code rather than starting under pdb, since you need an interactive terminal to control execution.

Common Workflow Tips

pdb is straightforward but powerful. Mastery of these commands makes debugging Python far faster than adding print statements and re-running code repeatedly.

← All posts