Is it a good habit to run in debug mode?
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开发者_C百科 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?
I've had this argument many times. The debugger is only a crutch if you use it like one. I've met people who refused to use a debugger even to get a stack trace of where a piece of code crashed, instead using printf bisection to find the crashing line of code (this would take a day or more.. seriously, people?)
One problem you might encounter when using a debugger is tunnel vision. The debugger has a way of focusing your attention on the immediate area where the bug became apparent -- whether it's a crash, incorrect data, or otherwise -- at the expense of stealing your attention from other areas that might benefit from some investigation. On the other hand, actually watching code execute in a debugger can sometimes free you from your mental trap of thinking about the code the wrong way. You might swear it does X when it actually does Y -- seeing it do Y before your very eyes is sometimes a profound moment.
That said, I only fire up the debugger in two circumstances:
- A bug manifested which, after five minutes or so, I cannot immediately guess as to the cause
- I'm trying to understand some code I'm not familiar with, and I want to watch it execute
Honestly, the time in the debugger is usually just a few minutes, then the problem is found. Fixing the problem is usually the hard part, and the debugger is of little use for that.
I think it's a mistake, not so much to always have a debugger at the ready, or to even run code always under the debugger, but to run a DEBUG BUILD. You already pointed out the worst of the problems with this. Memory allocations tend to happen differently, uninitialized data is filled with different values, etc. If the first time you fire up the release build is a few weeks before QA gets their hands on it (or, in a crazy shop, before you start shipping), you may be in for a world of serious pain.
I have only once seen a bug which only manifested in the debug build. A few people argued that it wasn't important because that isn't what we ship, but I looked into it anyway and found a REALLY bad problem.
Like any tool the debugger has appropriate and inappropriate uses. There are no bad tools.
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...)
Ultimately, you should run your tests in the same configuration your code will be running in the wild.
Then if a test fails, you can drop back to debug mode, and if it still fails, track it down and fix it. If it "fixes" itself when run in debug mode, then be glad you found it now rather than when you shipped, and get to tracking down the root cause in other ways.
Especially in GCC the compiler definitely likes to help you along, but honestly issues don't crop up very often.
I see nothing wrong with developing in debug mode, usually the only time you got odd behavior is when you aren't quite following the standards for the language anyway (not initializing variables, etc).
Once you're ready to release switch off debug and run tests again, locate bugs, rinse and repeat. I have very rarely come in contact with "debug mode only" bugs.
I like to run in debug mode during development. One big reason is simply so I'm setup to run the debugger when needed.
When I was doing more C++/MFC programming, I would put ASSERTS all over the place (or Tracing, as you described it) and caught many bugs and found many wrong assumptions in the process.
Who cares if it runs a bit slower? I say develop in debug mode. It's extremely rare that I have errors that turn up when I switch to release builds. But I generally start running release builds when I'm nearing completion. If I have some testers, I'd obviously send them release builds.
I found writing printf much superior over debugging in python. It is just because it is simpler and you do need to recompile. Watching variables even whit pydev in eclipse is painful.One of the reaso is that i was always "debugging" code that was not much than few tens of lines of code.
On the other hand whit larger projects in C I am using debuger. It is different that in C there are pointers and arrays and you want to observe structs and it is not simple to write simple printf to see if your serialization code works correct.
I always use the debugger. And I will always single step new code line-by-line. There's a whole generation of kids that debug with print statements. (especially for web development) IMHO that's why software state-of-the-art is lagging.
Of course, you have to run your unit tests with both debugging on and off, but I find true compiler bugs related to optimizations are rare.
精彩评论