Hunting the Bug
A bug is a mismatch between what a program does and what it should do. Debugging is the disciplined process of locating and fixing that mismatch by searching through the program's state—the current values of its variables—for the point where things first go wrong.
Effective debugging relies on two everyday tools:
| Tool | Mechanism | Purpose |
|---|---|---|
| Print debugging | Inserting statements showing variable values | Crude but effective visibility |
| Debugger | Setting breakpoints and stepping through | Precise state inspection |
Both tools serve the same goal: making the invisible state visible so you can see where it diverges from your expectations.
The Debugging Routine
A reliable routine prevents wasted time and blind guessing:
- Reproduce: Find an input that triggers the bug consistently. Unreproducible bugs cannot be reliably fixed.
- Localize: Narrow down where the state first becomes wrong. Confirm correct state early and squeeze the gap.
- Understand: Determine why that specific line produces the wrong value. Do not fix blindly.
- Fix and verify: Change the code and re-run your tests to confirm the fix works without breaking anything else.
The golden rule is to reason from evidence, not assumption.
Pitfall: Changing code randomly hoping the bug disappears ("shotgun debugging"). Without observing actual state, you cannot know if you fixed the real cause.