I am calling into a statically linked .dll, and I see this error:
I wrote both the .dll and the calling code. This error should not be occurring. I am wondering if anyone else has encountered it before? The .dll only contains about 10 lines of code, its just a test .dll to see how dlls work in general. It blows up when I pass a std::string back out of the .dll.
I am using Visual Studio 2012 and C++.
What I will try next
From Debug assertion... _pFirstBlock == pHead:
This problem can occur if one uses the single-threading libraries in a
multithreaded module.
Tomorrow, I'll try recompiling the Boost static libraries in multi-threaded mode (my .dll is set to multi-threaded static mode).
What I will try next
See Using strings in an object exported from a DLL causes runtime error:
You need to do one of two things
Make both the DLL and the client that use it both link to the DLL version of the CRT (e.g. not statically).
OR You need to make sure you don't pass dynamically allocated memory (such as is contained in string objects) across DLL boundaries.
In other words, don't have DLL-exported functions that return string
objects.
Joe
This seems to match whats going on, it blows up at the precise point where I pass a string back across a .dll boundary. The problem only occurs when everything is linked in static mode. Now that's fixable.
See Passing reference to STL vector over dll boundary.
What I will try next
See Unable to pass std::wstring across DLL.
Solution
I have a nice solution, see the answer below.
In this case, the problem is that I was passing a std::string back across a .dll boundary.
Runtime Library config
If the MSVC Runtime library is set to Multi-threaded Debug DLL (/MDd), then this is no problem (it works fine).
If the MSVC Runtime library is set to Multi-threaded Debug (/MTd), then it will throw this error, which can be fixed with the following instructions.
Memory allocated in Memory Manager A and freed in Memory Manager B ...
The problem is that memory is allocated on the .dll side, then that same memory is freed on the application side. This means that memory manager A is allocating memory, and memory manager B is releasing that same memory, which generates errors.
The solution is to make sure that all memory passed back is not allocated in the DLL. In other words, the memory is always allocated on the application side, and freed on the application side.
Of course, the DLL can allocate/free memory internally - but it can't allocate memory that is later freed by the application.
Examples
This will not work:
// Memory is allocated on the .dll side, and freed on the app side, which throws error.
DLL std::string GetString();
This will work:
// Memory is allocated/freed on the application side, and never allocated in the .dll.
DLL int GetString(std::string& text);
However, this is not quite enough.
On the application side, the string has to be pre-allocated:
std::string text("");
text.reserve(1024); // Reserves 1024 bytes in the string "text".
On the .dll side, the text must be copied into the original buffer (rather than overwritten with memory that is allocated on the .dll side):
text.assign("hello");
Sometimes, C++ will insist on allocating memory anyway. Double check that the pre-allocation is still the same as it was:
if (text.capacity < 1024)
{
cout << "Memory was allocated on the .dll side. This will eventually throw an error.";
}
Another way that works is to use std::shared_ptr<std::string>, so even though memory is allocated in the .dll, it is released by the .dll (rather than the application side).
Yet another way is to accept a char * and a length which indicates the amount of pre-allocated memory. If the text that we want to pass back is longer than the length of pre-allocated memory, return an error.
This is what assert() looks like when its expression argument evaluates to false. This assert exists in the Debug build of the C runtime library, designed to check for allocation problems. The free() function in your case. The Debug build add extra checks to make sure you are writing your code correctly. And tell you when it detects a problem. Like calling free() on an allocation that was already freed, the simple case. Or calling free() passing the wrong pointer value, the trickier case. Or calling free() when the heap was corrupted by earlier code, the much harder case.
This is only as far as they can take it, they don't actually know why your code got it wrong. There is not any way they can put a Big Red arrow on the code that corrupted the heap for example. The easy case is covered by the Debug + Windows + Call Stack debugger window, it takes you to the code in your program that called free(). Or std::operator delete for a C++ program. The harder case is very, very hard indeed, heap corruption is often a Heisenbug. Getting the assert to be repeatable so you can set a data breakpoint on the reported address is the core strategy. Crossing fingers for the easy case, good luck with it!
After edit: yes, having cross-module problems with a C++ class like std::string is certainly one of the problems it can catch. Not a Heisenbug, good kind of problem to have. Two basic issues with that:
The modules might each have their own copy of the CRT, objects allocated by one copy of the CRT cannot be released by another copy of the CRT. They each have their own heap they allocate from. A problem that got addressed in VS2012, the CRT now allocates from a process-global heap.
The modules might not use the same implementation of std::string. With an object layout that does not match. Easily induced by having the modules compiled with different C++ library versions, particularly an issue with C++11 changes. Or different build settings, the _HAS_ITERATOR_DEBUGGING macro is quite notorious.
The only cure for that problem is to make sure that you build all of the modules in your program with the exact same compiler version using the exact same build settings. Using /MD is mandatory, it ensures that the CRT is shared so there's only one in the program.
The likely cause: binding to wrong version of the Qt DLLs, especially when moving a project from VS2010 to VS2012.
This is due to different versions of the standard library and associated dynamic allocation issues.
I had the same problem after a Windows reinstallation. My Runtime library build was Multi-threaded Debug DLL (/MDd).
My solution was to remove *.user file of the visual studio project, remove the debug folder and rebuild the project.
Related
I've run into a strange problem. The Release version of my application seems to run fine, but recently when I switched to the Debug version, I got an access violation immediately on start-up. The access violation is occurring when a block of allocated memory is freed. All of this occurs in the constructor for a static variable.
I believe the problem doesn't occur in the Release version simply because I have defined NDEBUG there, which I believe disables assertions in the C runtime.
I've been able to narrow things down a bit. If I add the following code to the constructor before the usual calls, then I get the same error:
int *temp = new int[3];
delete[] temp;
This makes me think that something outside of this block of code is causing the problem, e.g., perhaps there is a problem with the way the C runtime is being linked. However, I'm at a loss to say what that problem might be, and after a day of poking at the problem I'm running out of ideas for where to poke next.
Any help would be greatly appreciated. I am using Visual Studio 2010 to compile the application and running Windows 7.
Thanks so much!
In Debug mode, additional checks are added; therefore it's not unusual for a program to run perfectly well in Release mode but to give an access violation in Debug mode. This doesn't mean that the Release version is OK; it only means that some error made when the Release version is running is not catched but is when running in Debug mode.
Debugging a corrupted memory problem in C/C++ is very hard because the error can be made by any other instruction affecting the memory. For example, if you have two arrays that follow one each other in the allocated memory and the first array is overrun, then it will corrupt the header put before the second array (each memory allocation is prefixed by an header; this header is used by the operators delete and delete[] when deallocating the memory). However, only when you will try to deallocate the second array that the access violation will occurs and this, even if it's with the first array that there is error in the code.
Of course, you can have other problems with the second array. For example, you can find that some or all of its values have been corrupted when trying to read from it. However, it's not always the case and in many occasions, it might behave perfectly well when reading or writing to or from it and you can have the exact same good behavior with the first array. It's not because you don't have any problem reading and writing to and from some array that you don't overstep its boundary and corrupting the memory above (or below) it. Sometimes, the problem will only show up when trying to deallocate the array and other times, the problem will show up otherwise; for example with the display of corrupted values.
I was able to produce a minimal example by cutting away essentially all of my application code. I reduced the InitInstance function to the following:
BOOL CTempApp::InitInstance()
{
int *temp = new int[3] ;
delete[] temp ;
return FALSE ;
}
Even with all of my application code stripped away, the problem persisted. After this, I created a new project in Visual Studio 2010, once again replaced InitInstance with my minimal version, and then added all of the Additional Dependencies from my original project in the linker options. With this configuration, the problem was reproduced.
Next, I started removing libraries from the list of dependencies. I managed to whittle the list down to a single third-party library which was causing the following linker warning despite being labeled as the debug version:
LINK : warning LNK4098: defaultlib 'msvcrtd.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
I think what's happening here is that the vendor has linked his debug library against the non-debug runtime. Presumably when my application calls delete[] there is some confusion as to what the parameters are for the call, and it is trying to delete a portion of memory I have not allocated.
I have tried adding the following to my Ignore Specific Default Libraries list:
libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib
as suggested here. However, the problem persists. I think the solution will be to contact the vendor and have them resolve the conflict.
Thanks again for your suggestions. I hope this answer will help someone else with debugging a similar problem.
I had a programming error like this in malloc's size:
buffer = (char *) malloc(cbHash + 1);
assert(buffer);
instead of:
buffer = (char *) malloc(cbHash * 2 + 1);
assert(buffer);
I was writing two times more in buffer but in debug mode it did worked fine but on release it did crash in assert, that's how I figured out my mistake. My question is: how does debug differ from release executable? and why I didn't get error in debug mode?
Because you were writing still in application's memory space. Also writing outside of allocated memory results in an Undefined Behaviour, not necessarily a crash. Writing outside of app's memory results in a crash, because system sees that application violates memory of other program and violation access error is issued. However if you stay within app's memory, system cannot tell anything, and programs enters the UB state.
That is a short basic explanation. There is a little bit more to it. If you are interested I suggest looking into address spaces and memory access rights.
Also debug mode often does not have any optimizations and contains debug symbols as opposed to release builds. They might contain symbols, but often don't.
The assert could fail only if malloc failed for some reason.
There are three main ways MSVC debug and release differ
Release uses the optimizer and debug does not
Debug includes symbolic debugging information in object files and release does not
The run time libraries are different.
One way the runtime libraries are different is in how malloc is implemented. The debug malloc allocates extra memory on both sides of your object and sets the extra memory to a bit pattern. When you free the memory, if the extra bits have been changed then your program has a memory overwrite bug and it will tell you so.
The debug heap allocates more memory than requested, and pads the "NoMansLand"-region before and after the buffer with a special signature. This is done to detect buffer overflows. When the memory is freed, the debug build checks the signatures and prints an error if it has changed.
The memory block itself is also initialized with special values, for msvcpp 0xcccccccc. In the release build, the memory is left as-is, and may contain any values. This is to try to detect coding errors that fail to initialize the memory. Maybe this could be a reason the debug build runs, while the release build crashes: If 0x00000000 is bad for the program, it doesn't crash with the debug build, but may with the release build.
A follow-up question to Memory leaks when calling ITK from Visual Studio DLL
I refined the problem to the simplest example.
struct A
{
public:
A()
{
mp_data = new int(0x42);
}
~A()
{
delete mp_data;
}
int* mp_data;
};
A a;
When such a global class is defined in a DLL, Visual Studio debug CRT reports that mp_data is leaked on application shutdown. Does anybody know a workaround except disabling leak reporting?
If you are calling _CrtDumpMemoryLeaks() at the end of the main function the behaviour is expected, since mp_data will be deleted after _CrtDumpMemoryLeaks() was called.
You would need to call _CrtDumpMemoryLeaks() after the last destructor of you static objects has been called (or rather in the last destructor after the memory has been freed) if you don't want to see these leaks (quite a difficult task, I wouldn't try it).
The cleaner approach is to allocate all your static objects on the heap instead (at the beginning of main), and de-allocate them at the end of main, and then you can call _CrtDumpMemoryLeaks() and won't see any memory leaks.
FYI static objects with constructors and destructors are considered bad anyways, because the order in which they are constructed/destructed is not deterministic, and because of that static objects often introduce bugs which can't be debugged easily.
Edit regarding Andrey's comment:
You could try to deactivate the automatic call to _CrtDumpMemoryLeaks by calling _CrtSetDbgFlag to unset the _CRTDBG_LEAK_CHECK_DF flag. If that works, you can add a static object which calls _CrtDumpMemoryLeaks() in its destructor. To make sure that this object is destructed last, you can use the #pragma init_seg(compiler) directive.
No clue if this will work... Other than that, all other solutions will most likely require you to modify the ITK library (which should be possible, it's an open source library after all?!).
Any of following solves the problem.
(1) Create a fake dependency of the DLL on MFC, or
(2) Use the solution suggested by smerlin: add this code next to DllMain
struct _DEBUG_STATE
{
_DEBUG_STATE() {}
~_DEBUG_STATE() { _CrtDumpMemoryLeaks(); }
};
#pragma init_seg(compiler)
_DEBUG_STATE ds;
I hit the same symptom in the course of migrating an internal library from static linking to load-time dynamic linking, and it turned out that the problem in my case was that the DLL project and the EXE project were linked to different versions of VC++'s runtime/MFC libraries (one was MBCS and one was Unicode).
In my case, the application and library were both using MFC, and the _AFX_DEBUG_STATE destructor which activates the CRT memory leak dump was being called twice, for two separate objects -- since the DLL and EXE linked to different runtime DLLs, static state in the runtime was effectively duplicated. One of the DLLs would unload and dump leaks too early and show a bunch of false leaks. Switching both projects to use the same character set resolved the separate runtime linkage and also resolved the false leak reports.
In my case, linkage to the two separate runtimes was unintentional and may have caused other problems anyway. This obviously wouldn't be the case when consuming third party libraries with a well-defined ABI where you have no control over what CRT the library is linked to.
Not sure if this would've be applicable in your case but I wanted to post in case it's helpful to others.
In MFC applications you can disable automatic memory leak dump by calling:
AfxEnableMemoryLeakDump(FALSE);
This is supported since Visual Studio 2010. For the documentation, see here.
I had the same problems in Visual Studio 2015. I tried all the solutions. The first solution with fake-MFC-dependency only worked if you choose compiler option /MT in your Dll. So your Dll and main application won't share the same heap. But often /MD is needed, e.g. if you want to share STL container or string objects between the Dll and your main application (Dll-boundary). If /MD is used, app and Dll use the same heap. So the first solution with fake-MFC-dependency didn't work for me.
I don't like the second solution by disabling memory-leak-detection in the main application. When you don't need the Dll with this call in destructor anymore, you have to remember to reactivate the memory-leak-detection in your application.
I found another solution so I didn't have false-memory-leaks anymore.
You only have to use the /delayload linker option for your Dll! That's all :-). It worked for me also with compiler option /MD.
Here you can read something about Dll-boundary (why to use /MD?).
And here you can read something about CRT compiler options in general.
When my application finishes, debug build in visual studio prints out all unallocated object and the sequence number of the allocation which was not freed. Then normally I just put in a call to _CrtSetBreakAlloc(x) where 'x' is the alloc seq number and get a convenient ASSERT at the moment of allocation. However this doesn't work when the leak happens in a COM object, apparently. Is there a simple way to use the allocation sequence number to get the execution to stop there?
I tried setting a conditional breakpoint in dbgheap.c and it doesn't trigger either, which I don't understand -- COM object is build as debug.
The function _CrtSetBreakAlloc will only work with the C runtime library your module links to. In this case, it will work with the C runtime library linked to your application. I'm assuming your COM object lives in another module (DLL presumably). If the COM object is statically linked to the C runtime library, then calls to _CrtSetBreakAlloc will have no effect over the module boundaries, because your app and COM module does not share the same runtime and heap.
Can you modify the source/build of the COM module?
I wrote my own reference counted memory manager c++ (for fun) and I'm sure it isn't perfect ;) . And now when I'm trying to use it I got random SIGTRAP signals. If I comment out every line which are in connection with that memory manager everything runs fine. Getting SIGTRAP-s instead of SIGSEGV is quite strange.
I know that SIGTRAP-s are thrown when the program hits a breakpoint, but no breakpoint is set. I read in an other thread that debug builds of the exe's and dll's must be up to date. They are up to date and so it is not the reason.
Does anyone know why is this happening?
After searching on Google I realized that those sigtraps are same as those warnings you get in MSVC++ saying "Windows has triggered a breakpoint in xxxx.exe. This may be due to a corruption of the heap, and indicates a bug blahblahblah"...
So it seems yes, unexpected sigtraps can indicate memory corrupction (quite strange...)
And I found my bug too. The MM is in a static library which is linked to a dll. And that static lib and the dll is linked to my exe. So there were two memory managers, one in my exe and one in my dll. If call the initaialization method of the MM. It initialized the MM in my exe but not in the dll so the dll went without init. I solved this by not linking my exe against that static library.
I'd throw in a guess that you might be calling mismatched new/delete or malloc/free implementations - So something was allocated by your memory manager but when the memory is released you end up with the default delete/free implementation.
Set a breakpoint on the signal and see whether there is free() or operator delete on the stack and whether that is the implementation of said function which you would expect.