Robert Martin's Artima article: Debuggers are a wasteful Timesink:
Since I started using Test Driven Development in 1999, I have not found a serious use for a debugger. The kinds of bugs I have to troubleshoot are easily isolated by my unit tests, and can be quickly found through inspection and a few judiciously placed print statements.
I consider debuggers to be a drug -- an addiction. Programmers can get into the horrible habbit of depending on the debugger instead of on their brain. IMHO a debugger is a tool of last resort. Once you have exhausted every other avenue of diagnosis, and have given very careful thought to just rewriting the offending code, *then* you may need a debugger.
Ron Jeffries, describing Kent Beck in the "Practices of the C3 Project":
Something goes wrong. The code doesn’t work. You start to think: "What could cause that to happen?" Kent doesn’t think about what the problem is. He just sets a halt in the system and lets Smalltalk tell him what the problem is.
Sometimes you’re right about what the problem is. If you’re really quick you’ll be able to tell Kent [Beck] what to edit in the window he’s already looking at. If you’re really quick.
Sometimes you’re not right about what the problem is. Forget it, he has already fixed it.
Train yourself to think about where to put the halt, not to think about what the problem is. Of course it’s a great feeling when you can reason to the problem. But we’re not here to make our brains feel good, we’re here to get the code working as quickly as possible. Setting the halt andletting Smalltalk tell you will help you build working code faster.
For fear of being called a blinkered XP groupie, I'm going to have to side with the second quote here (and with other Smalltalkers who have chimed in, despite never having programmed in the language myself)
If you have a problem: your tests have gone red, or you've been handed a bug report, you have two tools available to you: static analysis, or dynamic debugging. With static analysis, you look over the code, and in understanding what it is doing, you find the logical error that is causing the bug. With dynamic debugging, you step through the code until you can see it start going wrong, and then you fix it. In a good debugger, you can then hit continue after you've finished editing, and it'll all work.
Static analysis can work, and can be fast. Unlike Beck, I would give the offending code a once&ndash or twice-over eyeball before switching to the debugger; in case it's something obvious I missed. That said, if it's that amenable to static analysis, why on earth did I write the bug there in the first place? I'm not always that sloppy. Often, the problem requires a deeper look. That's where the debugger can save you time.
Adding a few printlns can also be useful, but its a very limited technique. Unless it's tracking the progress of a variable over the course of a long-lived loop, I have no idea how one can justify putting in a println as being more useful than setting a breakpoint at the same line, and then being able to examine all available variables, and evaluate arbitrary expressions in that context. Most of the time, the first thing you try to println is the wrong thing, or in the wrong place. Far better to be able to refine your investigation in the one pass than having to change the print statement, recompile and re-run.
I find, however, that the quality of the debugger is the biggest decider on whether I do static analysis or full debugging. In VisualAge for Java, I would spend far more time in the debugger than I have since in Eclipse/WSAD. Things that worked reliably and helpfully in VAJ&mdashrewinding the stack , fix-and-continue, object inspection, expression evaluation—only seem to work reluctantly or sporadically in Eclipse's front-end to the standard Java debugger.
If I'm reluctant to use the debugger, it's not because I don't want to use it, it's because I want it to be a better debugger.