Subscribe to our mailing list

* indicates required
Close

Tuesday, April 07, 2009

Turn off your step-thru debugger

Years ago, when I was first learning to program, I ran into a problem with some code I was writing, and I asked my mentor (an extraordinarily gifted coder) for some help. He listened as I described the problem. I told him all the things I had tried so far. At that time, I was quite enamored of the Think C development environment for the Mac. It had a fine step-thru debugger, which I was quite reliant on.

My mentor suggested a couple more approaches to try (and when I tried them, they worked, of course). Then he made a remark that has stayed with me ever since.

"I try to stay away from debuggers," he said. "A debugger is a crutch. You're better off without it."

I was speechless with astonishment. Here was someone who wrote massive quantities of Pascal and assembly for a wide variety of platforms -- and he never used a debugger! I couldn't have been more shocked if he told me he had perfected cold fusion.

"If you get in the habit of using a debugger," my mentor pointed out, "you'll get lazy. A certain part of your brain shuts off, because you expect the debugger to help you find the bug. But in reality, you wrote the bug, and you should be able to find it."

Still stunned, I asked: "What do you do when you have a really nasty bug?"

He said something I'll never forget. "I make the machine tell me where it is."

Make the machine tell you where the bug is. What a wonderful piece of advice. It's the essence of troubleshooting, whether you're trying to fix a car that won't start, trace an electrical fault, or debug a piece of software.

My friend (who did a lot of "realtime" programming in assembly, among other things) pointed out to me that there are many programming scenarios in which it's impossible to run a debugger anyway.

I took my mentor's advice and stopped using a step-through debugger. The only real debugger I continued to use (at that time) was Macsbug, which I occasionally invoked in order to inspect the heap or see what was going on in a stack frame.

Sure enough, I found that once I stopped using a step-thru debugger, my coding (and troubleshooting) skills improved rapidly. I spent less time in "endless loops" (fruitless troubleshooting sessions) and got to the source of problems quicker. I learned a lot about my own bad coding habits and developed a renewed appreciation for the importance of understanding a language at a level deeper than surface-syntax.

To this day, I avoid step-thru debugging, and find myself better off for it.

If you do a lot of step-thru debugging, try this as an exercise. For the next month, don't use a debugger. See if you can walk without crutches for a change. I'm betting you'll lose the limp in no time.

32 comments:

  1. Interesting point, probably one I should personally take on board as well :)

    ReplyDelete
  2. I like the idea, I'm going to give it a go for a month.

    I'm be interested to see what happens.

    ReplyDelete
  3. The most effective debugging tool is still careful thought, coupled with
    judiciously placed print statements.
    -- Brian W. Kernighan, in the paper Unix for Beginners (1979)


    On Plan 9 we generally run debuggers once the program has crashed. Plan 9 handily keeps the program in the 'broken' state and you can then attach the debugger and get a stack trace. This give you at least some idea where to start looking. The main thing I learned from single stepping is how many intructions malloc needs to work it magic (and my aching fingers)!

    ReplyDelete
  4. Anonymous8:06 AM

    I've never used a step-through-debugger. The main reason is because I spent years compiling manually with makefiles, and I didn't know how to get a debugger working with my code!

    Even when I've worked in a full blown IDE my main debugging technique is printf. This has definitely improved my debugging skills. It forces you to think through the problem and eliminate places where the bug could be, so you slowly narrow down the problem space. "Ah, it must be a corrupt stack, and the only place I'm doing a memcpy is here... so...".

    ReplyDelete
  5. As Maht pointed out, i suppose you use print statements to get runtime information then? But what is in essence the difference between that and using a step-thru debugger to look at variable values, except losing time to type the statements opposed to a click or two to set the breakpoint?

    ReplyDelete
  6. What if he had told you that "you need to learn good coding habits and develop an understanding of the language at a level deeper than surface-syntax." It seems like that is what he wanted you to learn. Would you have been as motivated or intrigued if he had told you that?

    ReplyDelete
  7. @Jeroen
    I think the point of the post isn't to say that dropping printf statements is a better(faster) approach, it's to say that by doing manual debugging you force yourself to review your code. This in turn helps you avoid similar errors in the future. In my own experience the problems I create are very rarely a nice easy line where I can set a breakpoint. Sure I can set a breakpoint, look at the registers, and continue. Or I can just quickly dump all of my variables and get the whole picture at once.

    For me an added byproduct of this mentality is that all of my programs use a library I wrote for layered debugging. Building this in from the beginning keeps me from having to "lose time" writing statements later on.

    ReplyDelete
  8. Anonymous9:00 AM

    There are other "better" ways to improve your coding skills. Looks like you'll also claim IDEs screw up your programming skills. You should look at improving your understanding of tools. Every tool is there with a purpose. Maximising the better outcomes of a tool is (and should be) completely in your hands.

    ReplyDelete
  9. grant: No, because "you need to learn..." doesn't tell me *how* to do that, and at that stage in my career, I actually thought a step-thru debugger was a good learning tool for the things you're talking about. I needed someone to come along and point me in a better direction.

    ReplyDelete
  10. Anonymous9:42 AM

    Silly. This may have been true 20 years ago, when APIs were simpler and longer lasting. Now with coders using more, increasing complex API systems I would advocate *always* stepping through new pieces of code, so that you can see exactly what the side effects of this code are.

    ReplyDelete
  11. Thanks Kas. That is interesting.

    I am demotivated by claims like "don't use the debugger". I am motivated by hearing about what things people value, why, and how to achieve them.

    I think that if he had told you the former, you would have said "Ok. How?".

    I'm not sure how much worse someone who *can't* write code would be if they just quit using the debugger and never getting any better (not citing you, just in general). You are clearly a motivated person; you don't represent the norm.

    ReplyDelete
  12. Interestingly I received the exact opposite advice from a guru early in my career - after you've written code, step through it once to make sure your understanding of what it's doing is correct.

    I can't say I've stuck to that, but it is a different approach to the same goal, making sure you have an accurate mental model of your code.

    ReplyDelete
  13. Anonymous11:11 AM

    There is no one rule fits all in IT. All such advice would go to trash, if there is a genuine production problem, with your manager near you breathing fire. Then you will try to get all kinds of tools out there to identify the issue and keep your manager happy. You cant go and make your shit (code) tell where the shit is. (Bug is)

    ReplyDelete
  14. 100% agree. I've been asked on a number of occasions what debugging tools I use. I often reply that it depends on what language I'm using at the time:

    In Java, I use "System.out.println", in PHP I use "echo", in JavaScript I use "alert", with trephine I use "print", in Ruby I use "p", in Python I use ...

    ReplyDelete
  15. Anonymous11:55 AM

    Good post.. However the best method to avoid a need for debugger I've found is writing unit tests.

    This transition happened after I managed to get rid of .NET and visual studio; it has amazingly good debugger, but yes, it'll teach you wrong things.

    Nowdays with eclipse and java I guess I could fire up the debugger, but isolating the problem with logging (slf4j/logback) and unit tests helps faster (I know how those classes work, and I've tested them throughly, so it has to be this.)

    ReplyDelete
  16. I've always found debuggers to be a PITA anyway. I avoid using them like the plague.

    ReplyDelete
  17. I agree with Pete Warden, and paradoxically with jasonmbaker; i don't like debuggers either, but i found them useful to be sure i understood what code was doing ay runtime. This is what makes me constantly improve my code quality and get closer to the utopia in which i wouldn't need one again ... But as pointed out by an AC, learning tools to , well, learn to code better and more productively is part of the game imho.

    ReplyDelete
  18. One thing stepping through in a debugger is crucial for, is when you're trying to find a mysterious bug in *someone else's* code. Tracing the execution helps you figure out how that code is working.

    ReplyDelete
  19. Anonymous2:31 PM

    Debuggers rule..
    Tools like firebug really warp your productivity AND insight in the code.

    Lol javascript was a pain until firebug. All those alerts.. I'm glad I got rid of them..

    ReplyDelete
  20. Anonymous4:58 PM

    Honestly I think this is absolute rubbish. You refuse to use something that makes you more productive because you think doing it "the hard way" is better for you? Seriously?

    And people pay you to waste time like that?

    ReplyDelete
  21. Anonymous6:05 PM

    I think it's more likely your mentor simply didn't know how to use a debugger effectively. They honestly sound like one of those loonies that cover up their ignorance under ridiculous "my way is best" assertions.

    Kids, don't listen to this cultist. A debugger is an extremely useful and effective tool for identifying problems.

    ReplyDelete
  22. Interesting, but I believe the truly mature programmer will know how to use all the high-speed tools available. (Like a debugger.) This doesn't mean you always have to use it-- but for times when you need it, it's really nice to know how to use one.

    BTW, Eclipse works great for Java or C++! (Netbeans, too, so I'm told).

    Best Regards,

    Rick

    ReplyDelete
  23. Anonymous9:21 PM

    Wow, chill out people. What I got from the article is to "avoid" debuggers, not rule them out completely. I started coding using print statements to debug and I use exactly the same principles today, except that in the right place, a debugger will provide alot more information with a single click.

    The principle of troubleshooting is still the same.

    ReplyDelete
  24. You are talking about two extremes, relying on the debugger completely, or not at all. The trick with this, as with all thing in life, is to find the right balance. A debugger is a very useful tool, and it can find certain types of errors very quickly, and other types of errors very slowly if at all. Learn when to use each of your tools.

    ReplyDelete
  25. Anonymous1:02 AM

    It's just like when old Ben told me to turn off the targeting computer on my run through the trenches. Just use the force.

    Seriously this is a stupid idea. Even when you used the debugger, it doesn't necessary tell you what the bug is, it just gives you the application state at each execution line. Knowing that your app failed because of a null value, only gives you the what. You still need to determine the why.

    ReplyDelete
  26. I don't use debuggers hardly ever. I started with print statements, and later wrote custom logger libraries to turn off the print statements. Now, log4j does the magic for me. And considering I can't use a debugger in production, it really pays off. Junit and TestNG have made good alternatives to excessive print statements. However, when I inherit someone else's code, which is filled with bad code/bad separation/bad SRP, then sometimes a step-thru debugger is my only option.

    ReplyDelete
  27. We called this technique "contemplative debugging".
    Here is my story:

    http://notbrainsurgery.livejournal.com/35925.html

    ReplyDelete
  28. Anonymous2:32 PM

    Having more than 20 years experience in large-scale software system development, I recommend this:

    When you are just starting out, a debugger can be very helpful. Essentially, it is a bit like "training wheels" for a bicycle. Typically, after some solid design experience, you will quickly lose further need for debuggers.

    Consider if you asked Lance Armstrong how often he puts training wheels on his bicycles? ;-)

    ReplyDelete
  29. You're missing one great use for a debugger: Not to help you debug your code, but to help you *write* it.

    When I'm working on some code, I write part of it, set a breakpoint at the end of the part I wrote, and let it run to there.

    Now as I write the next bit of code, I can see the *actual data* that I'll be working with in that code.

    It's so much easier than trying to do the same thing with just a mental model of what's in all the variables.

    ReplyDelete
  30. As much as I agree with you, in some senarios, it is almost impossible to not use debuggers. Try debugging deffered game code without using a debugger. Yes, it's possbile, but takes much more time, and time is something is that never on ones side when making games. Sometimes is just much easier to be able to break the program at certain points to be able to inspect if the data is corrupt or not. I guess one could use asserts and printf's but again, on multi-threaded systems this can be pretty hard.

    ReplyDelete
  31. Anonymous4:57 AM

    I have not got this sort of chess memory for debugging i don,t remember sets of code i would make a typing area programming could be easy extensible like Darwin and intuitive like modern Java i can,t believe that there are these clukie qicktime Java templates are lazy and java could be more intuitive and have more dream weaver magic basic programming should have some of darwin and some of dreamweaver and programmer should not be aloud to make program templates that work more like crystal cave these cryptic windows that are not that fun when you you put the information in just to push go and find that you have to start again there should be some
    java style that has drag and drop code that also lends from some of the best information programs like pro tools or dreamweaver

    ReplyDelete
  32. Anonymous6:05 AM

    the best program to come out was hyper text not for the program for the name programmers love anti social behaviour they don,t get out of tha house look what happened to the guy that made zip i hope some person like this does the ground work and finely puts programmers in a more creative and fast moving entertainment pose os they can get the work done and take out the rubbish and make the cover of vogue

    ReplyDelete

Add a comment. Registration required because trolls.