Wednesday, April 9, 2008

Do you have a theory?

In many cases when I sit with a novice developer who is working on fixing a bug I see him or her throwing lines of code from here to there. When I ask "why did you do that", usually when the code looks already like after a burglar paid a visit, the answer I get is "it wasn't working, so I'm trying to fix it."

Would you like someone to fix your car that way?

Debugging is considered sometimes a non-sceintific trial and error process - you try this and that, eventually the bug will be exhausted and you will break it. Well, it is not. This would only make you to mess your code and put new bugs in, break the original structure and leave the code in a strange, shaky position, usually explained later as "we needed to do that because there was a misterious bug in the original, proper code."

Just as when fixing your car, the mechanic would probably not try to shove your carburetor into the fuel tank as a possible solution (well, we haven't tried this yet, who knows maybe it works), this is not the way for debugging.

Debugging should be methodical.

  • Have a theory before you act
  • Try to prove your theory on a simple code
  • Divide and conquer - try to eliminate the bug by putting code in comments till the bug is gone, then analyze what is wrong in the lines commented out. But don't just throw these lines away, even if they look redundant at first sight, and don't move them around without understanding the problem
  • Analyze the problem and what causes the bug before you start changing your code, use logs to analyze the problem in complex scenarios
  • If you are changing the code as part of a theory ("I think we might have to call the super class at the beginning of the function and not at the end...") - remember what you have changed, if your theory fails (the bug persists and the change does not have a value of its own, it was just a whim of the moment) - return to the original code before you go on
  • If your theory prove itself right, still make sure that you fully understand it (moving the call to the super class to the beginning of the function fixed the problem - now let's understand why it should be this way... does it always have to be this way? do we need to check other similar places?)
And never try to shove your carburetor into the fuel tank, even if it makes the car go (maybe the problem was that the carburetor was too dry) - not understanding what you have done is NOT a fix!

1 comment:

Moshe Sambol said...

I'd like to add to your list the suggestion that while you're in there, if the code was mysterious but you're now figuring it out while debugging, add some comments explaining the code so that the next person won't have to go through the same thing all over again. And next time you write a piece of complex code, remember that in six months you or someone else will be in there debugging - sometimes a few clearly worded comments can save a lot of time!