Jump to content
  • Advertisement
Sign in to follow this  
SymLinked

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

This topic is 3293 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Advertisement
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
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?

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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!