Basic

Stepping with a debugger

The prints stopped narrowing because the value changed deep inside a call. That is the point of a debugger: stop at a line and look at every variable without editing the code.

What you will see

11

About 2 min of reading

Quick check

Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.

Try It

Drop a breakpoint, inspect live values, and step until the bug is visible.

1

A function with a bug. Drop a breakpoint before the return so you can inspect.

def score(n): total = n * 2 breakpoint() return total + 1

Before you run it, say out loud what it will print. Then open the answer.

What it prints
>>>
2

Call it. The program stops at the breakpoint and shows the live total.

score(5)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
-- (score) /home/blue/Documents/Website/DEV/main.py:3 -- >>> total = n * 2 (Pdb)
3

Inspect the live value at the stop. total is 10, so the bug is the + 1 at the return, not the multiply.

p total

Before you run it, say out loud what it will print. Then open the answer.

What it prints
10
4

Step to the return and see the wrong result come out.

n

Before you run it, say out loud what it will print. Then open the answer.

What it prints
11

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

breakpoint() pauses the program at a line, you read live variables there, and step line by line until a value changes wrong.
1 breakpoint() pauses at a line
↓
2 Read live variables
↓
3 Step one line at a time
↓
4 Bug is where a value changes wrong
Why this works
When to reach for it

Prints are enough for a bug one seam wide. A debugger earns its place when the value changes deep in a call tree, inside a loop that runs many times, or where a print would flood the log. It lets you stop at a line and read every live variable without touching the source.

The debugger is a loop

Set a stop, read the variables, step one line, read again. The bug is the step where a value changes wrong. This is the same bracket idea as prints, but the bracket is live state instead of printed text, so you can inspect anything, not only what you chose to print.

Examples

Set a breakpoint

breakpoint()

This line drops you into a prompt when the program reaches it. Nothing else changes, the program just pauses there and hands you the current variables.

Inspect at the stop

(Pdb) p total
10
(Pdb) p i
4

At the stop you type variable names and read their live values. No print needed, and you can change what you inspect without editing the source.

Step one line

(Pdb) n
(Pdb) p total
15

n runs the next line and stops again. Watch a value change line by line, and the line where it changes wrong is the bug.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Prints you can trust
Previous Lesson
Prints you can trust
Next Lesson
One test, many cases
One test, many cases →