The Zen of Debugging
"Wilkes was probably the first computer programmer to spot the coming significance of program testing: 'In 1949 as soon as we started programming', he recalled in his memoirs, 'we found to our surprise that it wasn’t as easy to get programs right as we had thought. Debugging had to be discovered. I can remember the exact instant when I realised that a large part of my life from then on was going to be spent in finding mistakes in my own programs.'" — Maurice Wilkes Obituary
Debugging Process
0. Is there a bug? syntax error? incorrect results? null pointer? array out of bounds? failed test?
1. Where is the bug? what line number? what function? (use the stack trace, Luke.)
2. When does the the bug happen? what inputs cause the trouble? can we find a simple(r) case?
3. How will we know if the bug is squashed?
4. Why is the bug happening?
5. If steps 1-4 are unclear, gather more evidence. [see B-F below]
6. What is the bug?
7. Propose a bug fix.
8. Goto 0
"The most effective debugging tool is still careful thought, coupled with judiciously placed print statements."
— Kernighan, Unix for Beginners (1979)
Making Debugging Easier
A. Develop and test programs incrementally.
B. Write tests: small unit tests & larger integration tests.
C. Use assertions to detect bugs early; fail fast.
D. Trace by hand; Or use a visualizer, debugger or print statements to gather evidence.
E. Talk through your program with a colleague or a rubber duck.
F. Never make random changes in hopes of fixing the bug; however, sometimes small changes can be used diagnostically to probe and gather information.
G. Follow coding standards, and use static analysis tools to flag likely buggy code.
H. Accept the fact that you will need to debug.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Kernighan and Plauger in The Elements of Programming Style.