Typically, debugging has been hard. I’m not talking about the kind where you made a mistake and could fix easily after a bit of inspection. I’m talking about the ones where it seems like things just go wrong, and you have no idea what to do or where to start to fix it.
In the beginning, it use to be when I debugged, I would just try random things until it worked. I quickly grew out of that, and almost always managed to figure out what was wrong, even if it was a painful slog. It was worse when I was using libraries. If the bug ended up being in a library with no documentation, I’d not know what to do. Digging into a library to see what was wrong? Inconceivable!
And when I got frustrated, I’d just re-run the same thing, thinking that it would magically change something this time around. Wasn’t it Einstein that said insanity is doing the same thing over and over again and expecting different results?
Nowadays, when debugging, I’ve found that asking myself a couple of pertinent questions helps with the debugging.
What’s the reported problem?
I hesitated to put this question in here because it’s something that’s second-nature to me now. But seeing nacent coders, they often times don’t read the error output and figure out what the computer’s actually complaining about. It’s too easy to just see “Argh, it’s not working!”, and have a mental block there.
Read the actual error! Where does the error occur and what’s the immediate reason for the error? If it doesn’t make sense, search the error message on stackoverflow. That’s a good start to understanding what the error means. If you don’t know where to see errors, find out. Ask around. Without some sort of error log or output log at the very least, you’re just flying blind.
What is it doing that’s different from what I think it’s doing?
When something goes wrong, I realize it’s usually an assumption that I have about the system that isn’t matched up to reality. The next step is to understand what the heck the system is doing instead of what I think it should be doing. This is a pretty important step that I’ve had a mental block on before.
How did the immediate cause for the crash or error come to be? What are the data and states that are coming into this function? What’s the sequence of events that lead up to the state?
How do I find out what it’s doing?
And lastly, if I don’t know what it’s doing, and I can’t tell what it’s doing, I usually ask myself how do I find out? Do I look at the log files? Is there a place where error messages are outputted? Are there debugging tools that will help me?
Often times, if the error is reproducible, then you can keep running it until you find out what it’s doing. If it’s a large system wide crash, then you ought to be sure that the system keeps a log of the important things that it’s doing.
It’s not quite like puzzle solving.
People have often compared debugging to solving puzzles. That conjures up in most people’s minds as doing something. However, in puzzle solving and debugging, most of your time is not actually coming up with fixes, tweaks, and solutions. It’s mostly spent understanding wtf is going on. Once you know what’s going on, the solution is usually fairly apparent.
When debugging, you should be spending time on resolving the dissonance between what you think should happen and what is actually happening, otherwise, you’re just wasting your time.