Sign in to follow this  
SymLinked

[MSVC]: Why would I want to use the Debug Runtimes when they "hide" bugs?

Recommended Posts

Hi guys, I've been running into lots of bugs now that we've switched to a release build. None of these bugs were apparent in the debug builds. So now I have to create a seperate configuration for a release build with debug information. What would I lose by changing the Debug Runtimes in our debug builds to a runtime that doesn't auto-initialization and that sort of stuff? Do I want to do that? Seriously confused. It's been a ton of work walking trough the release builds..

Share this post


Link to post
Share on other sites
They hide some bugs, but expose others. Its a trade off. By setting uninitialised or recently freed memory to certain patterns it can make it easier to spot when they are off, the downside is that these patterns are deterministic and the program might end up unintentionally relying on them.

I think that the quantity of bugs it tends to find far outweighs the number it masks.

Share this post


Link to post
Share on other sites
By having debug on, the errors it *does* catch are usually given up with a fair bit more info -- which goes a long way in squashing bugs.

You're right to assert that Release builds will also catch bugs, but you'd be wrong to assume, then, that the Debug build has no place. For most software builds, stick to Debug, but be sure to do a Release build from time to time during development (milestons, midway-points, or monthly perhaps, though this will largely depend on the size of your project.)

Share this post


Link to post
Share on other sites
To add to what the other posters have said:

In debug mode, your code isn't optimized, you have padding around memory used to detect when memory gets stomped, and there are functions that have different functionality in debug mode than release mode (different steps).

Because of those things, your code acts differently in release mode, and "what's important" in your memory resides at different addresses.

That means if you have some code that writes outsied of the bounds of an array, it may not write over anything bad in debug mode. But, in release mode, where important things are in different places, it may overwrite something really important and break things.

Debug mode isn't hiding bugs, you just have a "release only bug". They come up pretty commonly in software (:

You have to watch out for "release only bug" 's older brother too, the heisenbug. A heisenbug is a bug which disapears when you try to debug it.

Sometimes by putting in code (especially logging code) to try and debug a bug makes it disapear because it changes the timing of your code (in the case of multithreaded problems) or changes the layout of memory enough to where your bug isn't doing anything that causes a crash anymore.

Hope this helps :P

Share this post


Link to post
Share on other sites
Wow that's interesting!

So how do you guys set this up usually? Maybe like this?

Debug build (With debug information, CRT and unoptimized)
Release build (With debug information)
And a regular Release build that you ship.

Share this post


Link to post
Share on other sites
Quote:
Original post by SymLinked
Debug build (With debug information, CRT and unoptimized)
Release build (With debug information)
And a regular Release build that you ship.
I just have Debug & Release with debug information in both of them. Debug information doesn't actually change your executable at all - it just produces the extra .pdb file - so you just don't ship that if you don't want to.

But keep the .pdb files around, in case you ever need to debug a customer's setup!

Share this post


Link to post
Share on other sites
Quote:
Original post by Codeka
Quote:
Original post by SymLinked
Debug build (With debug information, CRT and unoptimized)
Release build (With debug information)
And a regular Release build that you ship.
I just have Debug & Release with debug information in both of them. Debug information doesn't actually change your executable at all - it just produces the extra .pdb file - so you just don't ship that if you don't want to.

But keep the .pdb files around, in case you ever need to debug a customer's setup!


I was under the impression that the executable got changed, not that there was a seperate file generated. Of course, I just tested it and you were right.

My problem is then solved, thanks!

Share this post


Link to post
Share on other sites
Quote:
Original post by Atrix256
hey codeka, with your setup, does your release w/ debug build do full otpimizations on the code?

If so, are you still able to debug it in any real way using the pdb?
Yes, it makes it hard to debug, but the Debug build is for "every day" debugging, I just include the debug information in the release build so you can get better stack traces and stuff, mostly.

If you have problems with your release build, you can disable optimizations temporarily - that'll at least give you the ability to debug more easily while still not initializing variables to known bit patterns that the debug CRT does. In practise, though, I've never actually had to do that...

Share this post


Link to post
Share on other sites
Quote:
Original post by Atrix256
hey codeka, with your setup, does your release w/ debug build do full otpimizations on the code?

If so, are you still able to debug it in any real way using the pdb?
Yes it can still do everything you configure it to, such as all optimisations. As noted, the debug info all goes in a separate file.

You can still debug it with the pdb file to some extent, barring several problems. A lot of variables, usually those that have a short lifetime, disappear as they get put into registers, and it gets 'interesting' trying to find their value. That's where the 'registers' and 'memory' windows come into play. This can get particularly unpleasant when it happens to the 'this' pointer.
No stepping into inlined functions, as they've actually been inlined - duh. It also does things like steps over multiple statements at once, and can even appear to step into the wrong function if you have multiple functions that compile down to the same code. E.g.
bool isEditable() {
return true;
}
bool isViewable() {
return true;
}

Worse still, the debugger sometimes gets confused about where things actually are and can give you totally bogus values.

With practice and skill you can usually work out exactly what it happening.

Share this post


Link to post
Share on other sites
Debugging in release mode pretty much requires debugging the assembly. This is actually pretty easy on PowerPC, and absolute hell on x86. Note that optimizations can be disabled on a per-function basis; if your compile times aren't too punishing, this can be a useful way to drill down to the bug without getting your hands dirty with LEA and JNZ.

Share this post


Link to post
Share on other sites
>>A heisenbug is a bug which disapears when you try to debug it.

Is that what theyre called, they are a major PITA, luckily I seldom run into them.

To the OP u should be doing a release build every 10 or so compiles, so these errors dont start building up.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this