Debug library crashes when linked with Release build

D

Dave Johansen

I just converted a solution from Visual Studio 2003 to Visual Studio
2005 and the Debug mode seems to be running just fine, but the Release
mode crashes on the following code:

std::ifstream in("myfile.txt");
float value;
in >> value; //The crash happens here in the getloc() function

The above code is actually from a library built in Debug mode that is
linked into the Release build of the executable. Does anyone have any
ideas of what could be causing this? Or how I could fix it (other than
switching the library to release mode, because that's currently not an
option)?

Thanks,
Dave
 
M

Mark Salsbery [MVP]

The library is a static library?

There can be big problems linking to two versions of the same library.
Each will have its own set of internal variables, each will have its own
heap, one of them probably isn't even initialized, etc.

Mark
 
D

David Lowndes

The above code is actually from a library built in Debug mode that is
linked into the Release build of the executable. Does anyone have any
ideas of what could be causing this?

You do! :)

Don't entertain mixing release/debug components or different compiler
versions where the interface between them is anything other than plain
old data types or ones which have a defined common scheme.
Or how I could fix it (other than
switching the library to release mode, because that's currently not an
option)?

You'll have to make it an option or redesign the interface - I suspect
the former is the easier of the 2 options.

Dave
 
B

Ben Voigt [C++ MVP]

David said:
You do! :)

Don't entertain mixing release/debug components or different compiler
versions where the interface between them is anything other than plain
old data types or ones which have a defined common scheme.


You'll have to make it an option or redesign the interface - I suspect
the former is the easier of the 2 options.

Just realize that debug vs release can mean several different things:

debug or release CRT
optimizations disabled or enabled
debug information generated or not

The only one of those that has to match is the first, feel free to create a
version of the library that uses release CRT (same as main application) but
no optimizations and creating debug database to make debugging easier.
 
D

Dave Johansen

Just realize that debug vs release can mean several different things:

debug or release CRT
optimizations disabled or enabled
debug information generated or not

The only one of those that has to match is the first, feel free to create a
version of the library that uses release CRT (same as main application) but
no optimizations and creating debug database to make debugging easier.

Sorry, I wasn't more clear about the exact meaning of "debug mode". I
was using the debug CRT, optimizations disabled, and debug information
being generated. I tried switching to the release CRT and it still
crashed in the same location. After playing around with it a little
bit, I switched the preprocessor definition from "_DEBUG" to "NDEBUG"
and that stopped the crash. I'm guessing that some struct/class is
being defined a little differently because of this, but does anyone
know for sure what is causing this?
Thanks,
Dave
 
B

Ben Voigt [C++ MVP]

Dave said:
Sorry, I wasn't more clear about the exact meaning of "debug mode". I
was using the debug CRT, optimizations disabled, and debug information
being generated. I tried switching to the release CRT and it still
crashed in the same location. After playing around with it a little
bit, I switched the preprocessor definition from "_DEBUG" to "NDEBUG"
and that stopped the crash. I'm guessing that some struct/class is
being defined a little differently because of this, but does anyone
know for sure what is causing this?

A lot of things in the headers are defined differently based on that macro,
and it needs to match the CRT.

Actually just defining one of those macros is usually enough to get the
right CRT linked in due to #pragma comment(linker ...) in the headers. Are
you using NODEFAULTLIB?
 
D

Dave Johansen

A lot of things in the headers are defined differently based on that macro,
and it needs to match the CRT.

Actually just defining one of those macros is usually enough to get the
right CRT linked in due to #pragma comment(linker ...) in the headers.  Are
you using NODEFAULTLIB?

Yes, I forgot to mention it, but I'm actually forcing it to exclude
the debug CRT using the NODEFAULTLIB command.
Dave
 
B

Ben Voigt [C++ MVP]

Dave said:
Yes, I forgot to mention it, but I'm actually forcing it to exclude
the debug CRT using the NODEFAULTLIB command.
Dave

Now that you've changed to NDEBUG macro instead of _DEBUG, you should not
need /NODEFAULTLIB any longer.
 
D

Dave Johansen

Now that you've changed to NDEBUG macro instead of _DEBUG, you should not
need /NODEFAULTLIB any longer.

Yes, I actually removed that. I was referring to its use when I was
linking in the library with the debug CRT in it.

But my question is why doesn't this work with Visual Studio 2005? It
worked just fine with Visual Studio 2003, so was it some sort of
intentional decision to make changes to the CRTs that would cause this
sort of problem? I realize that mixing the two CRTs probably isn't
recommended, but I don't see why it shouldn't be possible. There were
actual 2 libraries with the debug CRT that I was linking (one
internally maintained and the other from an external source), but the
company will only deliver a debug version. I was able to remove the
library from the external source to figure out the exact cause of this
problem, but it may be tough to get a release version of the other
library, so a change like this just seems like a BAD decision and
really limits certain uses of Visual Studio 2005.
Dave
 
I

Ismo Salonen

--snip--

It does no more work because some classes have different sizes in debug
vs. release mode. In debug mode ( _DEBUG defined) the classes contains
extra fields for runtime checks. When release mode is compiled the
classes memory footprint is smaller thanm in debug mode and debug mode
writes memory locaations it should not ( those, now nonexistent debug
variables).

This worked in 2003 because it did not have such sophisticated debug
helpers ( e.g iterator debugging). Using such combination
(debug&release) in same executable was never supported, it worked by
pure luck (or if you *really* knew what to do) .

br
ismo
 
D

Dave Johansen

--snip--

It does no more work because some classes have different sizes in debug
vs. release mode. In debug mode ( _DEBUG defined) the classes contains
extra fields for runtime checks. When release mode is compiled the
classes memory footprint is smaller thanm in debug mode and debug mode
writes memory locaations it should not ( those, now nonexistent debug
variables).

This worked in 2003 because it did not have such sophisticated debug
helpers ( e.g iterator debugging). Using such combination
(debug&release) in same executable was never supported, it worked by
pure luck (or if you *really* knew what to do) .

br
ismo

I think that the claim that it "worked by pure luck" is not correct.
It worked because there's no standard compliant reason why it
shouldn't. I understand that the debug mode now supports more advanced
checks and such, but there's no reason that this couldn't have been
done without maintain existing features (an additional preprocessor
directive that allowed the additional checks to be disable would have
solved the problem). I understand why things broke and the change
makes sense from a certain perspective, but claiming that it "has to
be that way" just isn't true.
Dave
 
B

Ben Voigt [C++ MVP]

Dave said:
I think that the claim that it "worked by pure luck" is not correct.
It worked because there's no standard compliant reason why it
shouldn't. I understand that the debug mode now supports more advanced

You can't hide behind the standard here, because you defined _DEBUG, which
begins with underscore+capital letter and as such is reserved for the
compiler or library implementation. When you start messing with reserved
identifiers you are completely implementation-dependent.

Beyond that, the standard requires that the one-definition rule be
respected. Frequently this requires having the same macro definitions
across the whole project, including static libraries, because although ODR
doesn't apply to macros, macros control the definitions of other things.
checks and such, but there's no reason that this couldn't have been
done without maintain existing features (an additional preprocessor
directive that allowed the additional checks to be disable would have
solved the problem). I understand why things broke and the change
makes sense from a certain perspective, but claiming that it "has to
be that way" just isn't true.

I believe there are other macros (why would you need a new directive???)
that control the extra checks.
 
D

Dave Johansen

You can't hide behind the standard here, because you defined _DEBUG, which
begins with underscore+capital letter and as such is reserved for the
compiler or library implementation. When you start messing with reserved
identifiers you are completely implementation-dependent.

Beyond that, the standard requires that the one-definition rule be
respected. Frequently this requires having the same macro definitions
across the whole project, including static libraries, because although ODR
doesn't apply to macros, macros control the definitions of other things.


I believe there are other macros (why would you need a new directive???)
that control the extra checks.

I agree 100% and I understand why things are the way they are, but I
still believe that they are this way by choice and not by some
external, uncontrollable force. The versions of Visual Studio prior to
2005 stand as a testament to this, because what I am trying to do was
allowed and functioned properly before Visual Studio 2005. I also
agree 100% that mixing debug and release libraries isn't recommended,
but that doesn't mean that it should be impossible.
Dave
 
D

Dave Johansen

I agree 100% and I understand why things are the way they are, but I
still believe that they are this way by choice and not by some
external, uncontrollable force. The versions of Visual Studio prior to
2005 stand as a testament to this, because what I am trying to do was
allowed and functioned properly before Visual Studio 2005. I also
agree 100% that mixing debug and release libraries isn't recommended,
but that doesn't mean that it should be impossible.
Dave

I did a little more digging and it turns out that the iterator
debugging stuff can be disabled (which fixes the problem I was having)
by defining _HAS_ITERATOR_DEBUGGING as 0. You can read more about it
here:
http://msdn2.microsoft.com/en-us/library/aa985939(VS.80).aspx

Thanks everyone for all of the help and advice,
Dave
 
D

Dave Johansen

I did a little more digging and it turns out that the iterator
debugging stuff can be disabled (which fixes the problem I was having)
by defining _HAS_ITERATOR_DEBUGGING as 0. You can read more about it
here:http://msdn2.microsoft.com/en-us/library/aa985939(VS.80).aspx

Thanks everyone for all of the help and advice,
Dave

I would like to make a correction and state that turning off the
iterator debugging didn't fix all of the problems that I was having
with mixing debug and release builds, so I guess that this is just a
semi-undocumented breaking change for Visual Studio 2005.

Dave
 
S

steeve.mercier

I would like to make a correction and state that turning off the
iterator debugging didn't fix all of the problems that I was having
with mixing debug and release builds, so I guess that this is just a
semi-undocumented breaking change for Visual Studio 2005.

Dave

Hi,

I went through the same frustration when I moved our company software
from VS 2003 to VS 2005. I also tried to fix with the
_HAS_ITERATOR_DEBUGGING=0, but with partial success only. Is there a
way to "emulate" the VS2003 behavior with regards to mixing debug and
release CRT? From the thread below, I understand that the only clean
way out of my problems would be to revise all APIs and use only basic
data types in them...

Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top