I have an application I'm working on that uses two third party libraries, each with pre-compiled libs and dlls, one of which provides necessary .lib files for both debug and release builds (A[d].lib) and the other which provides only .lib files for release builds (B.lib).
Compiling in Release mode (using MSVC9) works fine, however attempting to compile in debug mode fails because third party A requires LIBCMTD.lib (or MSVCRTD.lib) while third party B requires LIBCMT.lib (or MSVCRT.lib).
Can I work around this or am I stuck debugging in release mode?
Do you want full debug mode, or do you just want to be able to debug? If the later is the case, just go to the linker options, and turn on the generation of symbolic information (.pdb). This way you can use the debugger in your own code, step through the lines, and look at variables. If you get annoyed by the changes in control flow that the optimizers create, you can go to the compiler options, and turn off optimizations. This way you get to use the debugger AND build in release mode. Once you're happy with your code, you just change the settings back to creating optimized code.
Try passing /NODEFAULTLIB:LIBCMT to the linker.
I am not sure it can be done directly with static libraries. I suggest you package library B into a dynamic library, then use this new B' library. Your problems will have disappeared.
Related
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.
Brief introduction:
I am refactoring win32 application, I use VS 2008.
The application consists of both of my own dll and 3-rd party dll`s.
Issue:
When I run the application in the debug mode and execute some action the error is raised: the application programm has triggered a breakpoint, heap is corrupted.
Actions undertaken:
I have searched the internet and found that this error may be because of different build flags (multi-threaded debug /MD and multi-threaded debug dll /MDd) were used for dlls within the project(which results that they use different c runtime libraries, and for each library own list for work with memory is maintained this therfore can lead to the heap corruption).
I have checked my dlls - they all have the same flag: debug multithreaded dll. So I think that one of the 3-rd party DLL maybe was built with multi-threaded debug flag.
Questions:
Is it possible to find out with what flag 3-rd party library was
built, if so how can I do this.
How can I sort you my issue of
different build flags?
Is my guess about that error is due to
different build flags is correct?
Is it possible to find out with what flag 3-rd party library was built, if so how can I do this
Yes. C or C++ DLLs built with Visual Studio versions 2005 and 2008 require a manifest that states what version of the C runtime DLL they need. You can see it with VS, File + Open + File, select the DLL and open the node labeled "RT_MANIFEST". Resource ID 2 is the manifest that states the type and version of the CRT. It should match yours. Export it to make it easier to read. If it is missing then it either wasn't built with /MD or used a completely different version of VS, which in itself is bad news.
How can I sort you my issue of different build flags?
You can't. You'll need to contact the 3rd party and request a build that's compatible with yours.
Is my guess about that error is due to different build flags is correct?
It is possible but not terribly likely. Having a mismatch does not automatically cause a crash, a programmer can certainly design the DLL interface so that's never an issue. You can typically tell from the function signature and documentation. The problem case is where the DLL allocates an object and you are supposed to release it. It will be obvious when the function returns a pointer. Or a standard C++ class library object like std::string. Less obvious is when it throws an exception. Such a problem is also highly repeatable, it will bomb consistently, not occasionally.
The biggest mistake you are making is asking this question here. You should be talking to a programmer employed by that 3rd party that has worked on this DLL. He'll know the exact answer to your questions and can very easily solve your problem. If you cannot get this kind of support then you should not be using these DLLs, they'll make your life miserable for a long time to come.
I've tried Googleing this but I could not find a solution. I am trying to learn some basic C++. I wrote a simple hello world:
#include <stdio.h>
int main()
{
printf("hello, world\n");
return 0;
}
It compiled perfectly and everything! Great I thought, so I loaded up my virtual machine with XP and no service packs installed, then tried to run it. It told me I needed the MSVCR dll. Is there any way I can completely remove this dependency? I don't want to stuff the program with the dll. I want it to be gone, completely. Is it possible to make and run a program that will run in XP and up? Thanks.
It is technically possible to remove this dependency in C, but I'm not sure it is even possible in C++. And in either case, I would not recommend it. You lose a lot of stuff that the CRT does for you behind the scenes, most of which you don't want to have to reinvent yourself in an inferior fashion. For starters, it's the runtime library that actually calls your main function as well as calling the constructors and destructors for global and static C++ objects.
The best and simplest solution is probably to change how your application links to the runtime libraries. You have two different options: dynamically and statically. Dynamic linking is more memory-efficient and means that your application will take advantage of any bug fixes that are made to the library. It relies on the runtime DLL being present in order for your app to start. Static linking actually embeds the runtime library code into your application during the link phase of the build. This means that you can run without distributing the DLL, but there are important caveats.
For simple apps, it's unlikely that these caveats are relevant. Change the link style in use in your project's options:
Right-click on your project name in the Solution Explorer.
Expand the "C/C++" option in the left-hand treeview, and select the "Code Generation" item.
In the "Runtime Library" property combobox, choose one of the "Multi-threaded" options.
Debug builds should use "Multi-threaded Debug", while Release builds should use "Multi-threaded".
Do note that since you're using VS 2010, you can still choose to dynamically link to the runtime and gain all of the advantages of doing so without having to run the CRT installer on the target machines. All you need is the redistributable DLL(s) placed into the same folder as your application's executable. This makes deploying (and even testing) very simple and straightforward. You'll find these libraries as part of your Visual Studio installation:
\Program Files\Visual Studio x.0\VC\redist\
And of course, the debug versions of the CRT are never redistributable. Since you should not distribute debug versions of your application, this is not a problem. Make sure that you've compiled a "Release" build (using the drop-down combobox in the top toolbar), for which you will require only the redistributable libraries found in the above directory.
Can't I use the runtime that comes with XP?
There is no C runtime for you to use that comes with any version of Windows. Windows itself indeed depends on a C runtime library, but it deploys a private version of that library for its own use. Applications are not intended to link to it or make use of it in any way. You're on your own for deploying all necessary dependencies, and as you've noticed, you cannot assume that the target machines will already have the correct version(s) installed.
You can link the MS runtime statically, Project Options -> C/C++ -> Code Generation -> Multithreaded (or Multithreaded Debug for debugging configuration). No DLL should be needed then.
you can remove the annoying run-time library, do this:
project properties > linker > input > ignore all default libraries> yes
this will give you quiet a few issues you need to deal with, for example, floating
point numbers won't work, stack memory is very small (about 3k), there's no built in help against buffer overflows and such, and you can't use the standard library without copy pasting it in your project.
this will also decrease the size of the .exe nearly equivalent to as if it was hand made
in assembly.
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.
I have built Boost in Release configuration and have staged it into one folder.
Now when I add Boost libraries into project and try to build it in Debug configuration - linker fails because there are no Debug versions libraries.
Is there a way to make MSVC 9.0 use Release version of libraries when building Debug configuration?
Of course, there is an easy soultion - build Debug version of Boost. But I am just curious.
You can do two things:
Build the debug version for boost (this is the best option).
Add debugging symbols to your release build.
You can't use the release version of boost with your debug build because boost depends on the CRT, which is different in debug/release builds.
Exclude debug libs boost tries to link in (or disable with a preprocessor define, look into config.hpp) and manually include release versions.
That is, you could try that if not for runtime conflict...
(so that's a no)
1st... This is probably a bad idea, just build the debug libraries (or you can get them from my site).
If you still want to continue, try going in to the project properties -> Configuration Properties -> C\C++ -> Code Generation. Your "Runtime Library" setting will probably be something like "Multi-threaded Debug DLL (/MDd)", try changing this to the comperable option without the "Debug" in it and re-build.
I haven't actually gotten to try this myself, but I think it should work. I'm curious if you're successful :-)
I've just ran into this as well, and I have something to add:
I think the answer lies in boost\config\auto_link.hpp. It looks like including this file (which probably happens for all .lib / .dll, non-header-only, libraries) makes the generated .obj refer the debug version of the library.
Defining BOOST_ALL_NO_LIB will allow the linking to succeed, having the debug version of the program linked against the release version of the library. However, when actually trying to use Boost serialization linked like this I got an "Access violation reading location 0xabababeb", meaning that some pointer was left uninitialized. Perhaps this can be fixed by compiling something else in release mode, but it's probably better to just use Boost debug.