Magic from the Wayback Machine
/If you think that the current internet is a bit of a time sink, try taking a look at the past one.
I’ve been playing with the wayback machine, which has been carefully salting away copies of my deathless prose for around twenty years or so. I’ve just lost a big chunk time reading stuff I wrote ages ago. But some if it I rather like. Take this one, about debugging and magic that I wrote on 25th September 2003.
The Power of Magic
Been thinking about debugging (as one does). Debugging is what you do when the program doesn't work. Or works but does the wrong thing (nearly the same problem). The thoughts were prompted by a magic show on telly a few days ago. They showed the 50 best magic tricks (for which the number one was David Copperfield being chopped in half). Debugging a program is a bit like figuring out how a magic trick works. When I watch a magician setting up a trick I always want to jump up and go "No! That padlock is fake. There's an open link in the chain, you're hanging from a wire and that solid case you're going on about has got a trap door at the bottom. Oh, and what's that up your sleeve? And how come your assistant is twins?"
You get the picture... If everything the magician tells you is true, the trick must be impossible. This means that at some point he is telling you whoppers.
Broken programs are just the same. Something somewhere is not how it should be. Some part of the system is lying to you. This means that you debug the same way that you find out from a magician how a trick works; asking "Is the chain real?" etc etc.
Saying "It should work, I dunno why it doesn't" is tantamount to saying that you believe in magic. What you must do therefore is test all the things that you are assuming are true. "I know that this contains the customer number..." Really? How do you know? Did it start off with that number and change? Did the system that delivered the number send something else? Is the range of the numbers what you are expecting? And so on.
The worst thing that can happen is that you can end up convincing yourself that everything is OK. In that case you have what I call a "reality fault". And you start to believe in magic. At this point you have to resort to desperate measures:
First thing you do is walk away from the problem for a couple of hours. Often you will think of the answer; how the trick was performed. If that doesn't work, explain the trick to someone else. Two times out of ten you'll think of the answer during the explanation. One other time out of ten the someone else will tell you how the trick is done, or ask a question which changes how you view the problem: "Do you think he might have a fork lift truck in there somewhere?" or "What if the guy from the audience is in on it?".
Next thing you do is fiddle with the system in stupid ways. This is like asking the magician to perform the same trick, but using an elephant rather than his assistant. You might spot something this time. Send in completely invalid data. Send in lots of it. Send in lots of the same thing. This quite often gets you some behaviour which lets you track down the problem.
Then get the magician to do the trick in slow motion and freeze frame. Step through the code. Put in print statements. At some point you may well spot where your program does something it is not supposed to - and there you are at the solution.
Finally, run the trick backwards. The great advantage that a magician has is he knows how the trick will end. The audience doesn't. You can often figure out how it was done if you start from the result and try to figure out how to end up there. It is the same with debugging. Try to think how it could have ended up with that result.
OK. If you've done all that and it still fails you are in the one time out of a thousand where magic might actually exist. In this case you change the documentation and abracadabra! Your bug is now a feature! Failing that it is probably time to re-write the code.....