In Microsoft Visual Studio 2015 (v14.0) I have a solution that contains 3 projects.
Two of those projects are DLLs, and the other one is the executable.
The executable loads the DLLs at runtime and calls their functions and they exchange parameters; using Window's LoadLibrary, and GetProcAddress APIs.
In Release mode, when I set Runtime Library of my projects to Multi-threaded DLL everything works fine. This is Multi-threaded Debug DLL for Debug mode.
If I change to Multi-threaded for Release or Multi-threaded Debug for Debug I start getting Debug Assertion errors or Memory Access Violation errors and other kind of errors. (When I change it, I change it for all the projects in the solution.)
I need to use Multi-threaded option so that the executable won't need C++ runtime library on the target machine. How can I solve this issue?
It was because using /MT separates runtimes of entities (i.e. DLLs and executable), with each having their own runtime, hence their own heap, trying to allocate memory in one and freeing it in the other will end up in error. Because other modules were oblivious to the memory allocated.
On the other hand, with /MD all modules share the same runtime and as the runtime is aware of the memory allocated in one, it will be able to free it in the other. Because one instance of runtime manages the whole memory.
EDIT:
Thanks to dxiv comment.
Related
I have a DLL and 3 Applications which uses this DLL. (These application do not run simultaneously)
Out of 3 Applications, 2 work perfectly but 1 application doesn't get response from one DLL function after some time (at 7th function call, to be specific).
Also, The code works properly if I use debug version of Application OR my DLL. It stops in Release version only.
After spending 2 sleepless nights, I figured out that If I change project property of DLL from /MD to to /MT, this application works properly.
I have no clue why this thing is happening. Can anyone please explain this for the sake of a sleep deprived programmer!
Update:
I would be releasing this DLL in market and I can not say whether user application will be built is /MT or /MTD or whatever... Is there any way to make sure that it will work with any application.
In Windows speak, the EXE and DLL files are modules.
Each modules compiled dynamically (/MD) share one heap.
So in the dynamic modules, if one module calls malloc (or new)
and another module does the free (or delete) on the object all is good.
Each module compiled to link in the C runtime statically gets its own heap.
If one static module allocates an object and a different static or dynamic
module tries to free the object, the program will crash because the allocate
and free are against different heaps.
Allocating and freeing memory across module boundaries
/MD links the runtime as dynamic, if the computer you have a runtime properly installed, then compiling as /MT would work, since the runtime will be included in the binary.
That may also explain while it works when you compile it as Debug mode, in debug mode, a debug version of the runtime is statically linked into the binary.
Look here for some discussion about the topic.
UPDATE
Another problem may be that the modules that the dll were compiled with different options, as stated in this msdn article:
All modules passed to a given invocation of the linker must have been
compiled with the same run-time library compiler option (/MD, /MT,
/LD).
I have a question related to the setting of Multi-threaded Debug DLL (/MDd) and Multi-threaded Debug (/MTd). The difference between them is obvious: one is using dynamic library and the other is using static library. When I compile my program using /MDd, everything goes on very well. However, when I change the setting to /MTd and run the program, Visual Studio will trigger a breakpoint in the program with a pop-up message box. The message is as follows:
Windows has triggered a breakpoint in application.exe.
This may be due to a corruption of the heap, which indicates a bug in application.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while application.exe has focus.
The output window may have more diagnostic information.
I was wondering in this case what I can do next. Thanks!
It's possible that some other libraries you've included in your application are compiled against the DLL run-time library. If so, then when you try to link your executable against the static run-time library, you end up with two copies: one static and one dynamic. Depending on memory allocation patterns, this can cause one instance of the library to have incomplete information about the heap. Since the debug versions of the library try to detect heap corruption, you see the error. (Note that with the release versions, you might still have an error, you just won't get a notification.)
It's generally necessary to go all-or-nothing when deciding to link against the static or the dynamic run-time library. And, if you're including DLLs other than the standard OS ones, you almost certainly want the dynamic run-time so that everything in the process is using the same instance.
After checking the codes very carefully, I found another situation that can also trigger the same problem, and that is, the memory is located in one dll, but it is released in another dll. For more information on this topic, I refer to Memory allocation and deallocation across dll boundaries
Is it possible to execute debug mode DLL with release mode EXE?
I am trying this scenario but EXE does not load the debug DLL and throws error "This application has failed to start...".
I know this is not good scenario to do but Due to certain requirements I have to make this work.
It can work if your dll interface has no dependencies on classes that may look different in debug and release.
e.g. std::string and std::vector in MSVC are not compatible in debug and release. (Fences ...)
So for example
std::string GetName();
will not work.
In additional new and delete should not be shifted because debug/release use different runtimes. But anyway you should always delete in the same context(dll/exe) as new.
Yes, this can work.
Your "application has failed to start" issue is most likely you copied a debug build of the DLL (built on your machine with Visual Studio), to a machine that did not have the DEBUG CRT installed. Usually copying over MSVCRTD(version).dll to the same directory as your program files solves this problem. I have a previous answer that covers some of this here.
Best bet is to always have all your binaries linked to the same dynamic MSVCRT DLL so they all share the same runtime.
Another easy workaround is to compile your DEBUG DLL to use the same flavor of the MSVCRT DLL (or statically link to the CRT). Somewhere in the VS project propery pages (code generation I think) is the dropdown for choosing the CRT. There's nothing wrong with linking the retail MSVCRT into a debug DLL - or statically linking.
The things to watch out for are when you have a different flavor of the debug C runtime linked to the different binaries. If you have the release MSVCRT dll linked for the EXE, but the debug MSCVRTD DLL for the DLL, that can cause problems in a few circumstances. This is because handles and memory blocks are tracked by two different instances of the CRT.
Examples:
If you allocate memory in the EXE, but free in in the DLL. And vice versa.
File handles opened with fopen() in the EXE, but used or closed in the EXE (and vice versa).
For any of the header files for the DLL's interface, having any sort of inline functions or methods implemented in the header file is an easy way to cause #1 or #2 to happen.
Sharing STL objects (std::string, std::list, std::vector) is a definite no-no for mixed CRT usage.
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.
I would like some information on the runtime libraries for Visual Studio 2008. Most specifically when should I consider the DLL versions and when should I consider the Static versions.
The Visual Studio documentation delineates the technical differences in terms of DLL dependencies and linked libraries. But I'm left wondering why I should want to use one over the other. More important, why should I want to use the multi-threaded DLL runtime when this obviously forces my application into a DLL dependency, whereas the static runtime has no such requirement on my application user machine.
Linking dynamically to the runtime libraries complicates deployment slightly due to the DLL dependency, but also allows your application to take advantage of updates (bug fixes or more likely performance improvements) to the MS runtime libraries without being recompiled.
Statically linking simplifies deployment, but means that your application must be recompiled against newer versions of the runtime in order to use them.
Larry Osterman feels that you should always use the multi-threaded DLL for application programming. To summarize:
Your app will be smaller
Your app will load faster
Your app will support multiple threads without changing the library dependency
Your app can be split into multiple DLLs more easily (since there will only be one instance of the runtime library loaded)
Your app will automagically stay up to date with security fixes shipped by Microsoft
Please read his whole blog post for full details.
On the downside, you need to redistribute the runtime library, but that's commonly done and you can find documentation on how to include it in your installer.
Dynamically linking the runtime library can give you faster program start up times and smaller system memory usage since the dll can be shared between processes and won't need to be loaded again if it's already used by another process.
I think that main difference is how exceptions will be processed. Microsoft doesn't recommend to link statically to the CRT in a DLL unless the consequences of this are specifically desired and understood:
For example, if you call _set_se_translator in an executable that loads the DLL linked to its own static CRT, any hardware exceptions generated by the code in the DLL will not be caught by the translator, but hardware exceptions generated by code in the main executable will be caught.