Thursday, August 16, 2007

Debugging - Best Practices ...

For the coders among us, long live the debugger! Today's IDEs not only can profile and optimize your code, they come with top-class debuggers at no additional cost. The best also allow you to change values of variables, backtrack from a breakpoint, review the heap (and save it if you wish), and hot-replace code when it changes during a debug session. I can't even imagine developing software without such a tool.
But a debugger is as good as the programmer that uses it: if you are not skilled in using it, it's not worth the cost. A debugger is your first line in finding and fixing bugs. Here are other tips I've relied on over the years:
  1. Know your IDE's debugger limitations and features, and how to run it well. Only then can it be reliable and feasible.
  2. The obvious places may not be the culprits! After developing for a while, you start building a mental list of possible failure points and such, and develop a tendency of focusing too much on those areas when bugs do manifest themselves. Throw that mentality out and analyze issues from a "big picture" standpoint.
  3. Revert to the last working code and increment towards the the failure until you may find which additions cause the bug to happen. To this, you need a good versioning system. I've used Subversion, CVS, and Superversion - all free, of course.
  4. If there is a chunk of code causing the problem, contain the bug by using try/catch statements around it, and get a full error log. Then start walking that chunk, checking whether expected values are being set properly, and what is missing-in-action.
  5. Befriend the specification documents for insight. If you've debugged programs that use Windows system calls alot, you obviously don't have Windows source code to walk through, so MSDN (as scant as it is) will help some. Knowing what the WinAPI expects will help. Language forums are great help - chances are that you ain't the first person seeing this.
  6. Learn to read memory dumps, especially if you write C/C++ programs, or have to use JNI. Java hides these details from you, but Java debuggers should allow you to review entire data structures.
  7. Walk away from the code - take a hike, sleep, talk to your dog - whatever you do to take your mind off the issue. You won't believe how many times I've returned to the code and seen the problem right away - and felt so dumb.
  8. The blame game should start from inside out - first yourself, then the design, then the compiler, then the OS, and if you want - the language.
  9. Rewrite the offending chunk of code, perhaps using a different technique or even technology. Sometimes to understand C program issues, I've re-written chunks in Java and analyzed them from that standpoint. If you've fixed the same section nearly 5 times, it's time to re-write that piece afresh.
  10. Output messages - usually the first thing everyone does. I'm moving away from this - one of the 9 steps above will get me to the bug much faster.
Of course the art (notice it's not a "science") of debugging is different for everyone, but once you find a few good methodologies of finding bugs, work on making them better. Everyone should have a few tried and true ones, and then ask for help when bugs persist.