should I link to Debug or Release dll with same name? - c++

I was working on a MS Visual Studio project and noticed that the Debug build was Linking to a Release library (DLL), when a Debug library with the same name was also available. I switched the path to Link the Debug library, and it seems to still work. Is there any way to know if my change was correct?
Additional Information:
Using the debug DLL triggers a small memory leak that wasn't triggered with the release DLL. Or possibly that is debug related cache data. That leak made me question if it was including the lib headers without _DEBUG somehow. Thus this question.

It is the preferred way to link Debug builds of your program with Debug version of external dynamic libraries as it guarantees that uniform Visual C++ runtime libraries will be used. Mixing libraries built in Debug and Release mode will result in both Debug and Release VC++ runtimes being linked and annoying linker warnings about multiple symbol definitions in conflicting Debug/Runtime libraries.
Sometimes it may be inevitable as i.e. only Release version of some external library may be available. Hence in VC++ there are linker settings allowing to ignore some specific libraries. So you may start checking in the Linker-Input settings of the Debug build if such ignores are already defined for existing conflicts. With some luck you might be able to remove them now.
If using the Debug version of some library breaks the whole program it might be an insight how to improve the whole system, it is that what a Debug build is for anyway.

Assuming that it is the right library (as in the same code compiled to a different configuration), you are right to link to the debug dll on your debug configuration (and should link to the release dll on your release configuration).
The differences tend to be related to the optimisation level (Debug is usually compiled without any optimisation at all) and any symbols that might be included to make it easier to develop with and maybe step into.

Related

MFC100d.dll Issue in VS2010

I have a mfc c++ project on vs2010.
I am able to build it in both debug & release mode , but when I run it in debug mode, it gives the follow mfc100d.dll error. I have also installed C++ runtime environment vcredist_x86.exe still the issue is not fixed. Also I have set the Multi-threaded DLL (/MD) as the Runtime Library.
How do I fix it ?
The d suffix on the name of the DLL indicates that it's a debug version of the runtime DLL. That's confirmed by the fact that you say the problem happens when you try to run the debug version of the application.
By default, and for good reason, debug builds link to debug versions of the runtime libraries. These versions are not redistributable, and thus are not getting installed with the redistributable package (vcredist_x86.exe). That's not normally a problem: you aren't supposed to ship debug versions of your application.
The non-redistributable debug libraries are, however, installed with Visual Studio, so the debug version of your app should run fine on the computer you used to develop and build it. Which is likely the same computer you're going to use to debug it.
Also I have set the Multi-threaded DLL (/MD) as the Runtime Library.
Three important things to note about this:
You have to make sure that you set it for the correct build configuration (i.e. "Debug").
This is not recommended. Debug builds of your application should use the debug versions of the runtime libraries. They do a lot of things behind the scenes that help you to catch bugs. That's why they exist. If you don't want a dependency on the debug version of the runtime libraries, compile and distribute a Release build of your application.
That switch changes the version of the C/C++ runtime library that your application links to. The DLL you're getting the error message is an MFC runtime library.
The MFC headers test whether the _DEBUG preprocessor symbol is defined in order to determine which version of the runtime libraries should be linked in. Since _DEBUG is defined automatically in a debug build, it's linking in the debug version of the MFC libs.
To change that, you're going to need to do a lot of manual labor, undefining this symbol before you include the MFC headers, and then re-defining it afterwards.
Alternatively, you can statically link to MFC, which is a setting in your project's properties. But do be careful with this: you'll end up inadvertently mixing versions of the CRT, which can leave you in a world of hurt. Better to just ship release versions and keep debug versions for internal debugging.
Reinstalling the Microsoft SDK fixed this error.

C++ Linking release built library with my debug build

I've downloaded a 3rd party library, and built the .lib file in 'release' mode.
After adding the lib to my project, if i run my project in release mode, it's fine. But if i run my project in debug mode, i get an error:
_iterator_debug_level value '0' doesn't match value '2;
I could rebuild the library in debug mode, but I don't think I'll need to be debugging the library itself? And I've downloaded prebuilt 3rd party libraries before which only come with a release build (i assume?) that link fine whether my project is in debug or release. I'm wondering how that is done.
If you want to distribute a release library that others can use in either release or debug mode, you need to do two things:
Build a DLL, so that you get your own copy of the C runtime library
Not share CRT resources, such as the heap, across the library boundary. The biggest thing for C code is that dynamically allocated memory has to be deallocated on the same side of the boundary. For C++ code, you can use the std namespace inside your DLL, but not pass those objects across the boundary.
That's what the pre-built third-party libraries have most likely done. You can do the same thing with your library only if the external interface doesn't share CRT objects. Or you can build separate release and debug versions as static libraries.
Looks like your debug binary and the library you downloaded use incompatible iterator debug modes. Iterator debugging is usually controlled by macros. Depending on macro values the sizes of interators and many other objects can change. You are lucky that your program emitted useful error message instead of simply crushing.
Check the library documentation and make sure that your project uses the same iterator debug mode. You may also try recompiling the library in release mode. If that doesn't help, you would have to recompile the library in debug mode, even if you don't intend to debug the library itself.

Using debug/release versions DLL in C++

I am writing an C++ application that could be compiled under Linux (gcc 4.3) and Windows (MS VS08 Express).
My application uses third-party libraries,
On Linux , they are compiled as shared libraries, while
on Windows, there are two versions "Debug" and "Release".
I know that debug version provides extra support for debugging ( just like using -ggdb option in linux gcc, right? )
But I found that if my application is in debug version , the libraries must also be in debug version, otherwise the application will crash.
Why is there such a limit? It seems that there are no such limits in the linux world
Thank you very much!
The Debug configuration of your
program is compiled with full symbolic
debug information and no optimization.
Optimization complicates debugging,
because the relationship between
source code and generated instructions
is more complex.
The Release configuration of your
program contains no symbolic debug
information and is fully optimized.
Debug information can be generated in
PDB Files (C++) depending on the
compiler options used. Creating PDB
files can be very useful if you later
need to debug your release version.
Debug vs Release
It is also possible to debug your release build with the compiler flags.
Debugging Release Builds
Heap Layout - Guard Bytes to prevent overwriting
Compilation - Removing Assert/Debug Info
Pointer Support - Buffers around pointers to prevent seg faults
Optimization - Inline Functions
Common Problems When Creating Release Builds
To elaborate on Martin Tornwall. The various libraries linked when in Debug or Release
LIBCPMT.LIB, Multithreaded, static link, /MT, _MT
LIBCPMTD.LIB, Multithreaded, static link, /MTd, _DEBUG, _MT
CRT Libraries
Most likely, the Release and Debug versions are linked against different versions of the C++ Runtime library. Usually, a Debug build links against the "Multithreaded Debug DLL" runtime, whereas a Release build will generally link against "Multithreaded DLL". Loading DLLs whose runtime libraries are mismatched with that of the application will often lead to mysterious crashes.
You could try verifying that all your DLLs build against the same runtime library as your application, regardless of which configuration (Debug or Release) is active. Whether or not this is desirable is another question entirely.
The ability to choose which runtime library to link with enables the application developer to select the best feature set given her application's requirements. For example, a single-threaded application might incur performance penalties as a result of unnecessary thread synchronization if it is linked with a runtime library that is designed with thread safety in mind. Likewise, the consequences of linking a multi-threaded application against a single-threaded runtime could potentially be disastrous.
While I never intentionally link libraries that were built with different compiler settings, there isn't much point in doing so, I only know of the STL classes in the Dinkumware implementation (the one MSFT uses) to cause this problem.
They support a feature called 'iterator debugging' which is turned on by default in the Debug configuration. This adds members to the classes to aid the diagnostic code. Making them larger. This goes bad when you create the object in a chunk of code that was compiled with one setting and pass it to code that was compiled with the opposite setting. You can turn this off by setting the _HAS_ITERATOR_DEBUGGING macro to 0. Which is rather a major loss, the feature is excellent to diagnose mistakes in the way you use STL classes.
Passing objects or pointers between different libraries is always a problem if you don't carefully control the compile settings. Mixing and matching the CRT version and flavor gets you in trouble when you do so. This normally generates a warning from the linker, not sure what you did to not see it. There won't be one if the code lives in a DLL.

Link Error : xxx is already defined in *****.LIB :: What exactly is wrong?

Problem:
I'm trying to use a library named DCMTK which used some other external libraries ( zlib, libtiff, libpng, libxml2, libiconv ). I've downloaded these external libraries (*.LIB & *.h files ) from the same website. Now, when I compile the DCMTK library I'm getting link errors (793 errors) like this:
Error 2 error LNK2005: __encode_pointer already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir
Error 3 error LNK2005: __decode_pointer already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir
Error 4 error LNK2005: __CrtSetCheckCount already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir
Error 5 error LNK2005: __invoke_watson already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir
Error 6 error LNK2005: __errno already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir
Error 7 error LNK2005: __configthreadlocale already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir
Error 8 error LNK2005: _exit already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir
Documentation:
This seems to be a popular error for this library so, they do have a FAQ entry addressing this issue which ( http://forum.dcmtk.org/viewtopic.php?t=35 ) says:
The problem is that the linker tries to combine different,
incompatible versions of the Visual
C++ runtime library into a single
binary.
This happens when not all parts of your project and the libraries you
link against are generated with the
same code generation options in Visual
C++.
Do not use the /NODEFAULTLIB workaround, because strange software
crashes may follow. Fix the problem!
DCMTK is by default compiled with the "Multithreaded" or "Multithreaded
Debug" code generation option (the
latter for Debug mode).
Either change the project settings of all of your code to use these code
generation options,
or change the code generation for all DCMTK modules and re-compile.
MFC users beware: DCMTK should be compiled with "Multithreaded DLL" or
"Multithreaded DLL Debug" settings if
you want to link the libraries into an
MFC application.
Solution to same problem for others:
Huge Amount of Linker Issues with Release Build Only says:
It seems that your release build is
trying to link to something that was
built debug. You probably have a
broken dependency in your build, (or
you missed rebuilding something to
release by hand if your project is
normally built in pieces).
More technically, you seem to be
linking projects built with different
C Run Time library settings, one
with "Multi-Threaded", another one
with "Multi-Threaded Debug". Adjust
the settings for all the projects to
use the very same flavour of the
library and the issue should go away
Questions:
Till now I used to think that Name mangling is the only problem that may cause linking failures if its not been standardized. Just now I knew there are other things also which can cause same effect.
Whats up with the "Debug Mode" (Multi-Threaded Debug) and "Release Mode" (Multi-Threaded)? What exactly is happening under the hood? Why exactly this thing is causing linking error?
I wonder if there is something called "Single-Threaded Debug" and "Single-Threaded" which again causes the same thing.
Documentation talks something about "Code Generation Options". What Code Generation Options? WTH are they?
Documentation specifically warns us not to use /NODEFAULTLIB workaround. (example /NODEFAULTLIB :msvcrt ). Why? How would I cause troubles? what exactly is it?
Please explain the last point in the documentation for MFC users. Because I'm going to use MFC later in this project. Explain Why should we do it? What troubles would it cause if I don't.
Anything more you'd like to mention? I mean regarding similar errors. I'm very interested in Linker & its problems. So, if there are any similar things you can mentions them or some keywords atleast.
Whats up with the "Debug Mode"
(Multi-Threaded Debug) and "Release
Mode" (Multi-Threaded)? What exactly
is happening under the hood? Why
exactly this thing is causing linking
error?
The linker drags in libraries for several different reasons. The simplest is that a library is listed on the linker command line, or in the linker answer file on the linker command line. But any object files, whether compiled in your project or packed into a library, can also contain linker options including requesting particular libraries be linked in. In fact, the Visual C++ compiler automatically embeds such linker options matching the project options you use when compiling.
At link time, all the linker options from all object files and objects in static library files get combined. If more than one CRT library filename is requested, the linker reads in all of them and them you get naming conflicts, where the linker doesn't know which one to use.
I wonder if there is something called
"Single-Threaded Debug" and
"Single-Threaded" which again causes
the same thing.
There used to be, but the last few versions of Visual C++ have only shipped multi-thread compatible libraries.
Documentation talks something about
"Code Generation Options". What Code
Generation Options? WTH are they?
Look inside your project options.
Documentation specifically warns us
not to use /NODEFAULTLIB workaround.
(example /NODEFAULTLIB :msvcrt ). Why?
How would I cause troubles? what
exactly is it?
If you use /NODEFAULTLIB, all the linker settings stored within object files and objects in libraries get ignored. You'll end up with no runtime library and maybe missing other libraries. You can add them back in by hand, but it's still a big mess.
Please explain the last point in the
documentation for MFC users. Because
I'm going to use MFC later in this
project. Explain Why should we do it?
What troubles would it cause if I
don't. Anything more you'd like to
mention? I mean regarding similar
errors. I'm very interested in Linker
& its problems. So, if there are any
similar things you can mentions them
or some keywords atleast.
MFC applications and the MFC library have to use the same memory management functions, so that memory allocated by MFC can be freed by the application and vice-versa. FILE handles and other resources are also shared. The MFC DLLs are already compiled to use the CRT in a DLL, and in order to be able to share resources you need to use the same CRT, which means using a DLL too.
You need to configure project properties so that your debug build links with DCMTK's debug build and your release build links with DCMTK's release build.
The above is what you need to do. Below are explanations of some other random things you asked about.
Older versions of Visual Studio used to have single threaded libraries (release and debug versions) besides multithreaded libraries (release and debug versions). For your project you can pretend single threaded libraries never existed.
If you experiment with random ways to trick the linker into shutting up and leaving problems to be found by your customers instead of by yourself, you might find that the /NODEFAULTLIB option will do that. The makers of the DCMTK library are warning you not to do that because some other people did the same dumb thing in the past.
Whats up with the "Debug Mode" (Multi-Threaded Debug) and "Release Mode" (Multi-Threaded)? What exactly is happening under the hood? Why exactly this thing is causing linking error?
They are different versions of the C runtime library. You can statically link to the runtime library in debug and release mode. In the Code Generation Options (mentioned below), those would be "Multi-Threaded Debug" and "Multi-Threaded". The options "Multi-Threaded Debug DLL" and "Multi-Threaded DLL" dynamically link to the C runtime. By dynamically linking to the runtime, you'll also have to ship your installer configured to install the VC redistributable package that contains the proper runtime dlls for your version of Visual C++.
Statically linking to the C runtime is generally frowned upon, even by Microsoft:
In addition to all the methods
described above of distributing the
Visual C++ libraries DLLs, there is
one last option for building your
application which does not require you
to distribute the DLLs. However, this
option only works for native-only code
(it is not supported with /clr) and
leaves your customers seriously
vulnerable to any security holes as
well as adds a significant burden upon
yourself to patch all customer systems
should a vulnerability be found in any
of the libraries. This option is to
statically link in the libraries as
.lib files instead of dynamically
loading them as DLLs. You do this by
using the /MT flag on the cl.exe
command line (vs /MD), or selecting
the appropriate option in your project
properties through Visual Studio. You
may wish to use this option when
testing early debug builds of your
application on test machines before
you start working on setup. [See
footnote 3]
However, I can think of no scenarios
in which this is actually the right
thing to do when shipping your product
to customers. Basically, what this
approach does is pulls in the binary
code needed from .LIB files at compile
time, making it a part of your .exe or
.dll files. It increases the size of
your application, and there is no way
to update the libraries apart from
recompiling your application with new
.LIBs and redistributing your
application all over again. What this
means is that unless you go touch
every single machine which has
installed your application every time
there is a security vulnerability
found in the Visual C++ libraries and
completely reinstall your updated
binaries, you will be leaving your
customers vulnerable to attack. If
instead you use the DLLs, every time
there is a security vulnerability
found in the Visual C++ libraries,
Microsoft will install the update
centrally into the WinSxS folder via
Windows Update and all requests for
the DLLs will be redirected to the
updated version. This removes all
servicing burden on your side and also
allows the user to install one small
update which will touch all their
applications instead of replacing
every installed exe and DLL on their
system. Please, do not distribute an
application built by linking
statically against the Visual C++
libraries unless you have a system in
place for updating every customer
machine and also have a very good
reason to do so. At this time, I can
think of no circumstance under which
this would be the right thing to do
for a shipping application.
I wonder if there is something called
"Single-Threaded Debug" and
"Single-Threaded" which again causes
the same thing.
No such thing, see above.
Documentation talks something about "Code Generation Options". What Code Generation Options? WTH are they?
Right click on your Visual C++ project (from within Visual Studio) and select Properties. Under Configuration Properties->C/C++->Code Generation
Documentation specifically warns us not to use /NODEFAULTLIB workaround. (example /NODEFAULTLIB :msvcrt ). Why? How would I cause troubles? what exactly is it?
Take their advice and don't do it.
Please explain the last point in the documentation for MFC users. Because I'm going to use MFC later in this project. Explain Why should we do it? What troubles would it cause if I don't.
Because MFC is dynamically linked to the C runtime, using libraries that are statically linked to the C runtime will cause the linker errors you listed first in your post.
Anything more you'd like to mention? I mean regarding similar errors. I'm very interested in Linker & its problems. So, if there are any similar things you can mentions them or some keywords atleast.
From my experience, always dynamically link to the C runtime. It generally saves you a lot of headaches like the one you're experiencing right now.

How do I find the cause of this linker error?

After going through a lengthy process to rename a project, my DLL project will not build in Debug mode (Release builds work):
MSVCRTD.lib(msvcr90d.dll) : error LNK2005: _CrtDbgReportW already defined in LIBCMTD.lib(dbgrpt.obj)
This project, and the five static libraries it depends on, are set to use "Multi-threaded Debug (/MTd)" (under C/C++|Code Generation|Runtime Library). I believe LIBCMTD.lib is the one for multi-threaded debug, but what is MSVCRTD.lib, and what could be causing this error?
If it makes a difference, this DLL is for Windows CE.
LIBCMT is what you need for /MT, MSVCRT is what you need for /MD. You are linking .obj and .lib files that were mixed, some compiled with /MT some with /MD. That's not good.
Usually it is the .lib files that cause the problem. Review their build settings and make sure their /M option is the same as your DLL project.
Also, beware of the trouble you can get into if the DLL was compiled with /MT. You'll have major problems when the DLL returns pointers to objects that the client needs to release. It can't, it doesn't use the same memory allocator.
The MSDN article on LNK4098 has a very useful table: it tells you which libraries to manually add to the "Ignore specific library" list, depending on which CRT you're using. In your case, you should ignore all of these:
libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib
Observe that the reported library is in this list too. The problem is described in more detail in KB154753 ... libraries that a program will link with when built by using Visual C++
My interpretation of this is that in certain situations the algorithm that automatically picks which CRT libraries to link your code with will pick several conflicting libraries.
What is release set too? Setting a DLL to multithreaded debug can cause problems if you allocate memory that something accesing the DLL tries to free (they will be allocated in different heaps, for example). Try setting multi-threaded debug DLL.
Your link problem probably arises because a library you are linking to is expecting multithreaded debug DLL so the linker tries to link both and your link fails ...
The problem is the msvcr90d.dll is not in the windows ce image. It must be deployed with the application. The msvcr90d.dll is located in $(VCInstallDir)/ce/bin/$(ARCHFAM).
http://stackoverflow.com/questions/15959877/windows-ce-6-0-and-runtime-link-to-debug-dll-mdd