I saw a comment on another question (I forget which one) encouraging the asker to avoid testing his/her code in the debug harness unless strictly necessary, citing something to the effect of it acting as a crutch. There’s certainly something to be said for developing the skill to deduce the cause of bugs without "direct" evidence. I’m quite a fan of debuggers myself (in fact, I tend to only run without if strictly necessary), but I got to thinking about the relative merits of each approach.
Debugger Pros
- Starting with the obvious, takes less time to zero in on faults, exceptions and crashes
- Tracing provides a nice alternative to littering your code with commented-out print statements
- Performance overhead can give you extra wiggle room, i.e. if your program is responsive while debugging, it will almost definitely be so in the wild
Debugger Cons
- Performance overhead can make iterations slower
- (Edit) Tunnel Vision: Debugging the symptom can distract you from deducing the cause when the crash occurs long after or far from the defect
- It may "help" you by initializing variables or otherwise masking bugs, leading to surprises later on
- Conversely, there’s the odd bug that only crops up in a debug configuration; tracking it down may be a waste of effort (though, this is often indicative of a deeper, subtler problem that is worth fixing)
These are general, of course–it varies wildly with language, environment and situation–but what are some other considerations?
If you’re reasonably certain you have some bugs to deal with, running in debug mode tends to make finding them a bit faster. If you’re at the point that you think the bugs are gone, you want to simulate the target environment as closely as possible, which usually means turning debug mode off.
Depending on your language, tools, etc., chances are pretty decent that you can also do something that’s more or less a hybrid of the two: generate debugging information, but everything else like debug mode. This is often extremely helpful as well, so you can do debugging on the code after it’s generated the way the customer will see it (but beware that optimization can produce oddities, such as changing the order of code…)