How does debug differ from release executable? - c++

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.

Related

Debug Assertion Failed! Expression: _pFirstBlock == pHead

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.

Compare pointer to given value in C++

I'm on amd64 architecture. The following code gets rejected by the g++ compiler at the "if" statement:
void * newmem=malloc(n);
if(newmem==0xefbeaddeefbeadde){
with the error message:
error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
I can't seem to find the magic incantation needed to get it going (and I don't want to use -fpermissive). Any help appreciated.
Background:
I'm hunting an ugly bug which crashes my program while requesting memory in some STL new operation (at least gdb told me that). Thinking it could be some memory overrun of one of the allocated memory chunks being, by bad luck, adjacent to memory used by the OS to manage memory lists of my program, I quickly overrode new(), new plus their delete counterparts with own routines that added memory fencing; and while the application still crashes (all fences intact (sigh)), gdb now told me this:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000604f5e in construct (__val=..., __p=0xefbeaddeefbeadde, this=<optimized out>)
at /usr/include/c++/4.6/ext/new_allocator.h:108
108 { ::new((void *)__p) _Tp(__val); }
I noted that the pointer __p has as value the pointer representation of the value I used for one of my memory fences (0xdeadbeef), hence my wish to catch this earlier in my new() to try and dump out some more complex values in my program.
Additional note: the function where it crashes runs flawlessly a couple of million times before it crashes (intermixed with dozens of other routines which all also run a couple of thousand to million times), using valgrind does not seem like an option atm because it takes 6hrs and 11 Gb before my program crashes.
One of them is an integer, and the other a pointer. Perhaps an ugly cast would do
if(newmem==(void*)0xefbeaddeefbeadde){
For your question: you have 2 options - cast the pointer to 64bit number or cast the number to void*
For the background: as this takes too long, it could be a memory leak. So, try valgrind - no need to wait for crash, just run your program through valgrind and use the appropriate options. valgrind could help you to catch undefined behavior, too.
Another thing - compile your program with -O0 optimization level and with max level of debug symbols - -ggdb3. Also, if your executable does not generate a core dump, when this error occurs, make it generate. Then leave it working, while you're trying different approaches to catch the error.
In case you don't succeed, you'll at least have a (hopefully) nice core dump, that you can examine with gdb your_exe the_core_dump. Then, watch the core frame by frame, watch the variables, etc.
If it's not a memory leak, it could be a memory corruption somewhere, undefined behavior or something like this. If a good core dump is generated, you'll probably catch the error. Or, at least, it could give you useful information about the case.
Another thing, that could be useful, if you generate a core dump (no matter if it's a good or a bad one) - the size of the dump. If it's too large (the definition of "large" this depends on your program), then you most probably have a memory leak (it could be some kind of cross-reference issue, if you use smart pointers and if so - valgrind will not catch it)
That probably won't work that way. Next time when your program runs, malloc may never return that value. There is something else you must do, rather than just checking on the return value of new!

Variable Name from Memory address in Visual Studio 2008

My c++ application developed in Visual Studio 2008 crashes at some memory location. It is showing memory access violation erroe like,
Unhandled exception at 0x650514aa in XXX.exe: 0xC0000005: Access violation reading location 0x00000004.
how I can get the variable name assigned to 0x650514aa this memory location. Or how to debug this issue.
Thanks,
Nilesh
0x650514aa is the address of code (instruction pointer), not of a variable. If you're lucky, it's your code. Then a map file would help. If you're unlucky, it's some third-party code (blowing because you called it passing in nonsense). But it ain't pretty to dig through map files and it won't tell you your variables' values anyway.
However, if you run it from the debugger, the debugger should intercept and let you examine the stack. And even if you run it without debugger, just-in-time debugging should pop up a dialog asking whether you want to attach a debugger.
The other answers here have useful information. But if for some reason you cannot get the debugger to assist you, here's some more detail you can get out of that error message that may help you locate the problem.
Access violation reading location 0x00000004.
That memory location is what the program is incorrectly trying to read. Typically, reading or writing to a very low memory location like that is caused by code trying to use a NULL pointer as if it pointed to a valid object.
If you happen to know roughly what part of your program is executing when this error occurs, then examine it for any possibilities for NULL pointers to slip through unexpectedly.
Furthermore, 0x00000004 would be the location of a member variable 4 bytes from the start of the object. If the object has virtual functions, then it would probably be the first member variable in the object (because those first 4 bytes are the hidden pointer to the virtual function table). Otherwise, without virtual functions involved, there must be 4 bytes worth of other member variables and/or padding bytes before it. So if you can't immediately tell which pointer is going NULL and causing the problem, then consider which pointers are being used to read such a member variable.
(Note: Technically, the exact memory layout of non-POD objects, particularly when virtual functions are involved, is not guaranteed by any standard. Byte alignment settings in your project can also affect memory layouts. However, in this case it's fairly safe to assume that what I've described is what your compiler is actually doing.)
Usually, if you debug your application inside Visual Studio 2008, at the time of the crash it will stop right at the offending line. Be sure to compile in the Debug configuration, then click Debug | Start.
For further checking, you can go to Debug | Exceptions and check the boxes "Break when an exception is thrown".
If you're running in debug, you should be able to have the system break at that point and be able to see the source code.
If you're running in release mode however, you may need to use the .map file that can be generated. (Link switch /MAP, and you'll need to specify the export files too)
There's a description of how to for v6 here: http://www.codeproject.com/KB/debug/mapfile.aspx
2008 is pretty similar, I believe, although I tend to prefer to run in debug mode if possible.
The map file will allow you to translate your crash address into an exact location in the source code (line number), which may well be helpful. However it will only tell you where the error manifested - not what actually caused it (e.g. a stack corruption wouldn't tell you when you corrupted the stack, only when the corrupted stack was discovered.)
Still, it should help point you in the right direction.

Dereferencing deleted pointers always result in an Access Violation?

I have a very simple C++ code here:
char *s = new char[100];
strcpy(s, "HELLO");
delete [] s;
int n = strlen(s);
If I run this code from Visual C++ 2008 by pressing F5 (Start Debugging,) this always result in crash (Access Violation.) However, starting this executable outside the IDE, or using the IDE's Ctrl+F5 (Start without Debugging) doesn't result in any crash. What could be the difference?
I also want to know if it's possible to stably reproduce the Access Violation crash caused from accessing deleted area? Is this kind of crash rare in real-life?
Accessing memory through a deleted pointer is undefined behavior. You can't expect any reliable/repeatable behavior.
Most likely it "works" in the one case because the string is still "sitting there" in the now available memory -= but you cannot rely on that. VS fills memory with debug values to help force crashes to help find these errors.
The difference is that a debugger, and debug libraries, and code built in "debug" mode, likes to break stuff that should break. Your code should break (because it accesses memory it no longer technically owns), so it breaks easier when compiled for debugging and run in the debugger.
In real life, you don't generally get such unsubtle notice. All that stuff that makes things break when they should in the debugger...that stuff's expensive. So it's not checked as strictly in release. You might be able 99 times out of 100 to get away with freeing some memory and accessing it right after, cause the runtime libs don't always hand the memory back to the OS right away. But that 100th time, either the memory's gone, or another thread owns it now and you're getting the length of a string that's no longer a string, but a 252462649-byte array of crap that runs headlong into unallocated (and thus non-existent, as far as you or the runtime should care) memory. And there's next to nothing to tell you what just happened.
So don't do that. Once you've deleted something, consider it dead and gone. Or you'll be wasting half your life tracking down heisenbugs.
Dereferencing a pointer after delete is undefined behavior - anything can happen, including but not limited to:
data corruption
access violation
no visible effects
exact results will depend on multiple factors most of which are out of your control. You'll be much better off not triggering undefined behavior in the first place.
Usually, there is no difference in allocated and freed memory from a process perspective. E.g the process only has one large memory map that grows on demand.
Access violation is caused by reading/writing memory that is not available, ususally not paged in to the process. Various run-time memory debugging utilities uses the paging mechanism to track invalid memory accesses without the severe run time penalty that software memory checking would have.
Anyway your example proves only that an error is sometimes detected when running the program in one environment, but not detected in another environment, but it is still an error and the behaviour of the code above is undefined.
The executable with debug symbols is able to detect some cases of access violations. The code to detect this is contained in the executable, but will not be triggered by default.
Here you'll find an explanation of how you can control behaviour outside of a debugger: http://msdn.microsoft.com/en-us/library/w500y392%28v=VS.80%29.aspx
I also want to know if it's possible
to stably reproduce the Access
Violation crash caused from accessing
deleted area?
Instead of plain delete you could consider using an inline function that also sets the value of the deleted pointer to 0/NULL. This will typically crash if you reference it. However, it won't complain if you delete it a second time.
Is this kind of crash rare in
real-life?
No, this kind of crash is probably behind the majority of the crashes you and I see in software.

Does getting random SIGTRAP signals (in MinGW-gdb) is a sign of memory corruption?

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.