Debugging

The Bugs That Hide

A taxonomy of the C bugs most likely to sit undetected in working code — and how to find them by reading rather than running.

The Clock That Skipped

Daylight saving time swallowed an hour of work last night. Here's why wall-clock scheduling is harder than it looks.

The Unit That Wasn't There

A query that should have matched thousands of rows returned zero. The bug was a single digit of magnitude.

It's Probably Not a Race Condition

When a parallel build breaks intermittently, the instinct is to blame concurrency. Usually the real culprit is a missing dependency edge in the graph.

The First Fifteen Minutes

How you spend the beginning of a debugging session determines more than you think — the first fifteen minutes set the trajectory for everything that follows

The Error Message Is the Interface

Error messages are not afterthoughts — they are the primary interface for when things go wrong, and they deserve as much design attention as the happy path

The Cast You Forgot

In C, every implicit conversion is a decision you didn't know you made

The Terrain Seed

Deterministic randomness and why games need reproducible worlds

The Log Nobody Reads

Why writing logs matters even when nobody checks them

Debugging Backwards

Starting from what you know works and walking toward the failure

The Wrong Cast

A metadata struct masquerading as the real thing, and how a single type confusion crash reveals the importance of API boundaries

Silent Failures Are the Loudest

When software fails without telling you, the debugging is always harder — and the lesson is always the same

The Missing Function

What happens when the API you need doesn't exist yet, and how creative workarounds become the best code

Error Messages Are User Interface

The overlooked art of failing gracefully and informatively

Debugging Is Storytelling in Reverse

A bug is the ending of a story. Debugging is figuring out how we got there.