Debugging is a large part of Software Engineering, and it’s really important to have the right debugging mindset. Debugging itself is a wide subject. It’s something you think everyone knows, but in the real world everyone has to reinvent the wheel themselves.
It starts like this:
There is a problem with my code, and I want to fix it.
That’s one way to look at it. Another way is to say
There is something I don’t know about my source code.
There is something left for you to learn! Be interested. While I’m searching for the problem, I tend to fiddle a little bit with the code. Rename some variables, move functions from one class another or reduce visibility from a method from public to private (if it’s possible). This helps me understand*.
Next to really understanding what is going on, there is another thing that has to be part of your debugging mindset. You have to assume the code is wrong, even if you’ve written it yourself and it’s beautiful. If there wasn’t something wrong with the source code, you wouldn’t be debugging right now**. You have to feel responsible for solving the problem at hand.
Part of your debugging mindset: be relaxed
Another thing about your debugging mindset is that you have to be relaxed. It’s something that’s hard to do in a hurry. It’s about understanding the situation, and making a hypothesis about what is wrong. You should feel confident about this hypothesis. It doesn’t happen often that the hypothesis that you make is wrong.
Be a little bit suspicious Someone might have tried to make a fix for this problem at a different location, this fix might stop your real fix from working.
The next step is to gather a lot of data. Data can come from a lot of sources
- The compiler. Configure it to the pickiest level of error reporting. Fix every error, warning and even all the notices. If you get many errors, fix the first error first. Don’t trust the ones coming after, since they are unreliable, and might be just followups from The First One.
- Tracing with a debugger
- Log statements
There might be cases where all of this isn’t even enough. Sometimes you won’t find the cause straight away, because you get a non-precise error message. In that case you should think what you want to know, and then improve the error message, or enhance (or introduce) logging. This is closely related to defensive programming.
And with that bombshell it’s time to end the first part about debugging. Right now it might feel a bit vague, but go on to part 2: real life debugging!
* Not everyone thinks this is a great idea though, see refactoring legacy code.
** Unless of course you are that one person who finds the bug inside the vendor code.