Software Craftsmanship & Practice
Debugging & Problem Solving
Treat debugging as a disciplined search for a root cause, not a guessing game: reproduce the failure reliably, bisect toward its source, and fix the actual cause rather than the symptom in front of you.
- "select isn't broken" — assume the bug is in your code, not the platform, standard library, or compiler, until you have specific evidence otherwise
- Reproduce reliably first — a bug you can't reliably trigger can't be verified fixed, only hoped-fixed
- Binary search / bisection narrows down where a bug lives — halve the search space each time, including
git bisectfor "when did this regress" - Fix the root cause, not the symptom — patching where a bug is visible instead of where it originates tends to have it resurface elsewhere
- "Rubber duck debugging" — explaining the problem out loud, step by step, to anything (a colleague, a rubber duck) frequently surfaces the wrong assumption before the explanation even finishes
"select() isn't broken" is a decades-old piece of Unix folklore that generalizes well: the standard library function, the compiler, the framework you're using has been run by millions of people before you and almost certainly works as documented. The bug — the overwhelming majority of the time — is in an assumption your own code made. Starting the search there first, rather than "it must be a platform bug," resolves nearly every debugging session faster.