Part 3 · 2 chapters · ~12 min

Debugging as Problem Solving

Debugging as hypothesis testing, minimal reproductions, bisection over commits, time, inputs and configuration, rubber-duck explanation, changing one thing at a time, reading the error message properly, and when to step away.

6

Bisection, everywhere

code
git bisect start
git bisect bad HEAD
git bisect good v1.41.0
git bisect run npm test -- --grep "fee rounding"     # automatic: git tests each midpoint
git bisect reset
BISECTION
finding the bad commit among 64 in six steps
c1good
swipe the figure sideways, or tap expand for full screen
1/4
the setup
Commit 1 was good, commit 64 is bad, and you do not know which change broke it. Reading 63 diffs is slow; testing each is slower.
a known good and a known bad point63 candidates
7

Minimal reproductions and other habits

debugging habits
  1. Read the whole error, including the first line of the stack that is your code.
  2. Reproduce reliably; a bug you cannot reproduce cannot be shown fixed.
  3. Minimise: remove everything that does not affect the bug until a few lines remain. Often the cause becomes obvious during minimising.
  4. One change at a time, with a prediction of what it will do.
  5. Explain it aloud (to a colleague or a rubber duck): the gap in your explanation is often the bug.
  6. Step away after an hour without progress; fresh eyes and sleep solve a surprising number of bugs.