| name | debug |
| description | Systematic debug protocol — reproduce with minimal test, 2+ hypotheses, fix root cause, add regression test |
/debug — Systematic debugging
Never make random changes hoping they work. Follow this process.
Step 1 — Reproduce with a minimal test
Before investigating, write the smallest possible test that demonstrates the bug:
#[test]
fn test_bug_reproduction() {
let storage = MemoryStorage::new();
let result = do_thing(storage);
assert_eq!(result, expected);
}
If you cannot write a test that reproduces the bug, the bug is not well defined.
Go back to the user and ask for more information.
Step 2 — Formulate hypotheses (minimum 2)
Hypothesis A: [what you think is wrong]
Evidence in favor: [what observations support this]
How to verify: [concrete experiment]
Hypothesis B: [another possible cause]
Evidence in favor: [what observations support this]
How to verify: [concrete experiment]
Do not assume the first hypothesis. Always consider at least one alternative.
Step 3 — Verify each hypothesis
tracing::debug!("value at point X: {:?}", value);
dbg!(&structure);
static COUNTER: AtomicU64 = AtomicU64::new(0);
COUNTER.fetch_add(1, Ordering::Relaxed);
Verify hypotheses in order, not in parallel.
Once a hypothesis is discarded, document why.
Step 4 — Fix in the right place
❌ Patch the symptom:
if result.is_err() { return Ok(default_value); }
✅ Fix the root cause:
// The problem was that X did not initialize Y correctly
// Fix: initialize Y before using X
The fix must be the minimum change that resolves the root cause.
Do not take the opportunity to "clean up" unrelated code (that goes in a separate commit).
Step 5 — Regression test
#[test]
fn test_btree_does_not_lose_keys_after_split() {
...
}
Add the test to the permanent suite. Never delete it.
Debugging tools in Rust
RUST_BACKTRACE=full cargo test test_name
RUSTFLAGS="-Z sanitizer=address" cargo +nightly test
RUSTFLAGS="-Z sanitizer=thread" cargo +nightly test
cargo +nightly miri test test_name
cargo add tokio-console