Yeda AI Tips · #069

Español

Trap Every Crash Before You Fix It

Never fix a crash without trapping it first. In native code, a crash, memory leak, or data race is not gone when the symptom disappears — it comes back the next time someone (or some coding agent) touches that code path, unless something in the build guards against it. The guard is a failing regression test, written before the fix, and run under a sanitizer forever after.

The rule: test first, then fix

  1. Reproduce the bug as a failing test. Tell your coding agent: "write a regression test that reproduces this crash — do not fix anything yet." Run it. Watch it fail. A test you never saw fail proves nothing.
  2. Fix the bug. Now the same test flips to green, and you know it flipped because of your fix — not because the repro was wrong.
  3. Run the test under a sanitizer in CI. A sanitizer-instrumented build turns silent corruption into a loud, precisely-located failure, so the same class of bug can't sneak back in a form your assertions don't check.

This is exactly the loop where coding agents shine: the failing test is an unambiguous target, and "make this test pass without deleting it" is a prompt that's hard to game.

Which sanitizer traps which bug

Bug classSanitizerCompile flagTypical cost
Crash / memory corruption (use-after-free, buffer overflow, double-free)AddressSanitizer (ASan)-fsanitize=address~2x slowdown
Memory leakLeakSanitizer (LSan)-fsanitize=leak (on by default with ASan on supported platforms)Near zero until a leak-check pass at process exit
Data raceThreadSanitizer (TSan)-fsanitize=thread (add -O1 -g for usable output)~5x–15x slowdown, ~5x–10x memory
Undefined behavior (signed overflow, null deref, out-of-bounds subscript)UndefinedBehaviorSanitizer (UBSan)-fsanitize=undefinedLow

On Windows, MSVC ships ASan since Visual Studio 2019 16.9: compile with /fsanitize=address — works at any optimization level on x86/x64.

Why sanitizer coverage beats line coverage

Line coverage tells you a statement executed. It says nothing about whether that execution scribbled past the end of a buffer, read freed memory, or raced another thread — the program keeps running and the test stays green. A sanitizer checks every memory access and synchronization event during those same test runs, so the identical test suite catches an entire class of bugs that line coverage is structurally blind to. Your regression tests are only as strong as the build they run under: run the suite once normally, and again under ASan/UBSan (and TSan for concurrent code).

Power-user moves

Resources

Building an AI feature? Yeda AI designs, audits, and ships production LLM systems.

Talk to us · Read the blog · Leer en español