The art of debugging

In a perfect world, our software never run in an unexpected way.

Unfortunately, we don’t live in a perfect world, so sometimes (quite more than sometimes) we have to face some strange errors.

That’s when we must learn the gentle art of debugging

Follow me through easy steps and you’ll wipe the bugs out of your life

1) A bug never appears “sometimes”

Believe me, the word “sometimes” has been invented for losers. A drunk would say he “sometimes” gets drunk, but in my opinion he gets drunk EVERY TIME he drinks too much. That’s another way to live your life. “Sometimes” means you don’t know when. You can’t live this way. You are a programmer.

So, you must know when your script has a problem. Exactly. Try to replicate it. Insert breakpoints, print variables, do whatever you can to recreate the problem EVERY TIME you want.

Do you want an example? … let’s see this script

a = a random number between 0 and 9
b = 10/a

This script sometimes crashes… but you must know when it crashes… and we can say the script crashes EVERY TIME a = 0, because of a divide by zero error.

When you can describe the problem starting with EVERY TIME, proceed to step 2

2) A bug never appears for the sake of appearing

Believe it or not, Gods aren’t upset with you. There isn’t any virus in your computer. “THEY” aren’t trying to drive you mad, and leech your brain because they want to rule the world.

The bug appeared for a reason. In the previous example, the reason was a number cannot be divided by zero. It’s not a plot against you. You simply cannot divide a number by zero.

You must understand why your script does not work… in this case it was a division by zero error, you have to find your case.

Now you know when the bug appears, and why it appears

3) A bug is a useless creature

Ok, bugs are the only good actors I can see in horror movies for a couple of years, but they are quite useless… and maybe they can survive to a nuclear war, and I don’t really want to survive to a nuclear war just to face giand radioactive bugs, so make up your mind, you don’t need bugs.

I mean you must find a way to get what you want with no risk to encounter a bug. In our example, you must decide if you really need a random number between zero and 9, or if a number between one and 9 would do.

With numbers from 1 to 9 you solved the bug, but sometimes you may decide you need the zero too, and in this case you would perform the division only if the number is different than zero.

This is the step where you must decide if you want to obliterate the bug or handle it as an exception.

Needless to say the first option is the best, because you can manage one, two… maybe five… TEN exceptions, but sooner or later your script will collapse if you work this way.

4) Put a big shoe on the bug’s head

It’s the time to rewrite the bugged code… keep in mind what your script is intended to make, and what you don’t want to happen. Since at this time you will probably are a bit tired, proceed step by step. Throw a shoe to a bug from a big distance, and you’ll miss it. Get closer and closer, until… SQUASH! It will know the power of the mighty shoe.

5) It wasn’t a simple bug. It was a cyborg bug

If your bug dies with a little red light fading away, and you can hear something like “I’ll be back”… then it wasn’t a simple bug… it was a cyborg bug. In real life, fixing a bug can bring new bugs to life.

In my previous example, I can fix the bug setting a as a random number between 1 and 9.. but I can fix the bug coding the second line as b= 10/(a+1).

According to what I am expecting from the script, one of the ywo ways of fixing the bug can make the bug return later. You have to forecast future bugs and prevent them

That’s all… this was obviously an ironic post, but there is some truth in it… how do you debug your scripts?

  • For runtime bugs where all you have is a general class it’s located in, then I usually just start adding traces between lines of code. You can usually narrow it down to single line of code this way.

    The really hard bugs are the ones where you’re getting an error or unexpected results from a line of code, but because it’s not getting the correct input from some of the lines before it. Then your only option is tracing all of the values that act as input to that line back upstream through your code, and that’s a royal pain.

    I’ve had some luck finding memory leak and runtime bugs with De MonsterDebugger. It gives an overwhelming amount of info about your application as it runs, but sorting through it is a bit challenging.

  • Although I appreciate the irony, I have to say that if you iron the irony off (no pun intended) a lot of good advice is written here.

    As an example, in your point 1, if what I’m experiencing or being reported is that a bug happens sometimes and I’m clueless about it, I don’t attack it immediately, I leave it there, open a ticket on our system (sounds fancy but it’s just a shared google document) so I don’t forget it and let it happen time and time again. Sooner or later I’ll have an Eureka moment “Ah! I know what’s going on!” and fix it, usually quickly.

    I admit I don’t have a strategy apart from having a bug tracking document and a load of TODO lines commented everywhere inside my code and not actively chasing bugs. That’s how I organize myself and coding keeps flowing without hickups. The whole process is painless even when there are a lot of bugs around. Then I take a day off, refactor the code and debug it and it’s nice clean for the next cycle.

  • Xodus

    I liked this post because it is used for every programmer, regardless of how they are making their game. I look forwad for more posts like this, maybe one on optimization?

    Anyway, really nice and simple post!

  • Joel

    I can usually tell where it went wrong (usually where I added new code). So I just tinker, repair, replace or scrap.

    Optimization however is where my abilities are lacking, a guide on that could be very useful AS2/AS3 please :)

  • Good post, really enjoyed reading it :D

  • Matt

    I had a bug a couple days ago that appeared for the sake of appearing. It spent hours rewriting code trying to find the problem and fix it. I finally got frusterated and closed flash. The next time I opened flash, my code worked perfectly. It was a bug with flash, not my code.

  • Pingback: Link Dump Sunday (June 28th, 2009) - Porter’s World()

  • pault107

    @Matt

    I’ve been a Flash developer for almost ten years and I can honestly say that the same thing has happened to me around twenty times.

    Very frustrating. Especially as you start to lose faith in the Flash IDE and restart when it is in fact a real bug.

  • This is a great help thanks for the tips, i am really interested in debugging so i view this and i am happy to be here to learn.
    You can visit this squeeze page i hope this helps.

  • Thomas (I’m finally back!)

    @ Matt

    You closed flash and your new code wasn’t saved, so it worked perfectly. :D

  • Pingback: Emanuele Feronato’s Art of Debugging « The Asylum()