Great post over at Hacknot about debugging: "Debugging 101". I've been doing this crap for 20 years, so it's not like any of this is new, but it's certainly interesting to see it all written down in one place, and even though I've done it all, I don't neccessarily remember it every time :-)
A couple of highlights/issues:
Wooden Indian: I can't remember how many times over the last decade or so I've done this with Tim Wolf, and him with me, back when I was working at the OTI building in Raleigh. It just always seemed to be so funny to be describing a problem to him, when he really had no idea what I was working on in general, and just a few interesting questions from him, and the lightbulbs start going off in my head. And vice versa. And of course, asking lots of questions is an important way for junior folk to learn from their elders. Hint: I know I ramble; don't be afraid to call me on this.
Avoid Debuggers: I take issue with this. To me, that's like saying don't use them fancy compilers; they're just a crutch; you should write all your code in ASM! Perhaps learning to use a debugger properly is the key. Here are two of Mr. Ed's points:
- How often does it happen that you spend an extended period of time carefully stepping through a piece of code, statement by statement, only to find at the critical moment that you accidentally "step over" rather than "step into" some method call, and miss the point where a significant change in program state occurs? In contrast, when you progressively add trace statements to the code, you are building up a picture of the code in execution that cannot be suddenly lost or corrupted. This repeatability is highly valuable - you're monotonically progressing towards your goal.
It's not like adding code to the problem isn't going to cause it's own problems; not that it always does, but it sometimes does; and unless it's actually logging code you're adding, you're going to have to remove/comment out/neuter that trace code before you back into your team repository (or production). Which you will someday forget to do.
In fact, I frequently debug exactly like the tracing description; add breakpoints to help narrow down the interesting points where I want to watch what's happening.
- I've noticed that habitual use of symbolic debuggers also tends to discourage serious reflection on the problem. It becomes a knee-jerk response to fire up the debugger the instant a bug is encountered and start stepping through code, waiting for the debugger to reveal where the fault is.
That's just silly. It's a tool. Not a magic eight ball. Folks who wait for the debugger to show them the problem quickly stop using debuggers, since debuggers don't do this.
It's not like a nice 'graphical' debugger will save your ass every time. There are plenty of other things that you will sometimes need to do (read the article!). But I'd be screwed if I couldn't use a nice debugger like Eclipse's Java debugger for debugging the incredibly complicated Java code that I live in. In fact, I typically do my 'launches' under debug mode; bonus with Eclipse (at least when using a J9 VM, not sure about the Sun VM) is you get tasty hot code replace when you run under debug.
I have a long history with 'graphical' debuggers. When I started my IBM career I was doing CICS application programming in PL/I. The debugger the system shipped with, CEDF, would only pause before and just after your system or database calls. You couldn't step through your code at all. Even see it. Shortly before I moved onto my next job, we got a trial usage of a product called Intertest (which appears to still be around). Oh. My. God. Stepping through code, a line at a time. Inspecting local variables. It was like freaking magic. It costs an arm and a leg, but I managed to convince the folks on site that we absolutely needed this.
Later, when I was one of those OS/2 hippies, I wrote RxD, which I think was using the coolio text editor control that was the day job. That was fun. Nothing like actually writing a debugger.
In Smalltalk, it was fairly easy to hook into the debug system, so I did some whacky stuff like audio break points; set a .wav file to play when a statement was hit. Nothing like listening to your code 'play'.
Man, am I old, and a geek.