How to find reason for app crash on close? - c++

My Qt5 app crashes when I hit the close window returning:
MyApp(28741,0x7fff7aa73000) malloc: *** error for object 0x7fc40bc8e300: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
The program has unexpectedly finished.
Classic approach to recover it, I guess, is to disable application modules (should I say parts of it, when things are not so well organized) systematically until the problem appears.
Is there some (more) intelligent way to solve this issue?
From what has been returned the problem is obvious, there is pointer somewhere being deleted (at least) two times. But were is this thing hiding?
What can I do with 28741,0x7fff7aa73000? And with 0x7fc40bc8e300? Can I use those to find something in Qt Creator 4 on Mac?
Because the app crash on close it means the problem is in a destructor?

From what has been returned the problem is obvious, there is pointer somewhere being deleted (at least) two times. But were is this thing hiding?
Not exactly; what you say is normally signaled as a "double free"; this seems more like somebody is passing to free something that never came from malloc.
To pinpoint it, do as the message says:
*** set a breakpoint in malloc_error_break to debug.
(or really, even just run it under a debugger; normally on Linux it does break into the debugger at the top of the stack when the program is aborted)
Once the breakpoint is hit, walk up the call stack and see what pointer is being freed, and try to find out why it is being freed when it doesn't actually come from malloc.
The fact that the address is "big" (0x7fc40bc8e300) tells that it probably comes from the stack (if OS X is anything like Linux, the heap is "down" in memory, the stack is at the opposite side of the virtual address space), so probably it's just as simple as somebody passing to free or delete an address that comes from the stack. This often happens when you erroneously pass a stack-allocated object to some method that wants to take ownership of it and free it with free or delete when it isn't needed anymore.
Also, running valgrind never hurts, but I doubt that in this case it can be of any help - you don't seem to be dealing with an invalid pointer (which it would detect at the first read/write), but you have a valid non-heap-allocated pointer that is being incorrectly deallocated with free. It will probably detect it at the same time as free itself.

Related

Debugging a Corrupted Object on the Heap

I'm debugging a non-trivial software project where I have a bunch of objects located on the heap. At some point in time (at least) one of these objects gets corrupted.
I added a const member to my class to serve as a canary and indeed, it gets corrupted during executing. Typically I'd add a watchpoint to this variable to figure out when the memory is written to. However, I don't know which instance gets overwritten, as any information stored in the class gets corrupted as well.
I have too many objects to set a watchpoint on each of them and I haven't been able to reproduce with a smaller input set. Running valgrind I see "Invalid read of size 4", which is my canary int of 4 bytes being read but at this point it's already too late.
Any suggestions on how to proceed from here?
Probably this won't be specific enough, but when I had a similar problem, here is what I ended up doing. I'm assuming you can reproduce your problem in a deterministic fashion.
My strategy was to find which instance caused the problem first. This I did with a counter on a specific line that exposes the symptom. For example, on Visual Studio, I would setup a breakpoint that triggers on the 100000th hit, so that it never does; but Visual Studio still tells you how many times the breakpoint is encountered during execution. By trial and error, I would find that the problem occurs on the say, 20th time the breakpoint is encountered, and so I would set the breakpoint to trigger on the 19th iteration, to be able to discriminate the appropriate instance before corruption occurred.
Starting from there, I could have the address of the variable that was corrupted before it was, and play with the debugger to find out what is going on: gather enough information about the faulty instance.
Then, I did setup breakpoints at strategic places, which were triggered by conditions : eg. trigger only for an instance with the appropriate address, or with specific values in members.
You'll probably get to when the symptom occurs precisely, but not to the problem, but that's still something.
Hope this helps!
Running valgrind I see "Invalid read of size 4", which is my canary int of 4 bytes being read but at this point it's already too late.
You are confused: if valgrind told you that you are doing invalid read (presumably because the object has been freed), then you are reading danging (already freed) object, and that is exactly your problem.
You shouldn't try to access such objects, and the fact that your canary has been changed / corrupted after you freed / deleted the object is irrelevant.
I managed to find out what was causing my issue. Turns out the object I was looking at never existed in the first place. Like #employed-russian, I wondered whether my object might have been deleted somewhere I wasn't aware of. Putting a breakpoint on the destructor yielded nothing so the only reasonable explanation is the pointer itself being invalid, pointing to memory that wasn't a valid instance of my class.
Lo and behold; the pointer I was dereferencing was left uninitialized by some constructor of another class. I figured it out when I added an explicit check for null and Valgrind's error became Conditional jump or move depends on uninitialised value(s). By using --track-origins=yes, I quickly figured out the source of the uninitialized data, i.e. the pointer missing from the initialization list.
(I know uninitialized values can be detected by the compiler with -Wuninitialized but apparently my version of clang (apple) didn't feel like mentioning it with -Wall enabled.)

C++ - Debug Assertion Failed on program exit

When calling 'exit', or letting my program end itself, it causes a debug assertion:
.
Pressing 'retry' doesn't help me find the source of the problem. I know that it's most likely caused by memory being freed twice somewhere, the problem is that I have no clue where.
The whole program consists of several hundred thousand lines which makes it fairly difficult to take a guess on what exactly is causing the error. Is there a way to accurately tell where the source of the problem is located without having to comb line for line through the code?
The callstack doesn't really help either:
.
this kind of errors usally appear if you delete already deleted objects.
this happens if one object is given to multiple other objects that are supposed to take ownership of that first object and both try to delete it in their destructor.
As the messagebox already suggests, you're probably corrupting your heap in some way. Either you free/delete some memory block that you should not or you're trying to write to some memory block that has already been freed/deleted.
The callstack suggests that this is probably happening when stepping over the last line of your main function. If that is the case, then the problem is probably in the cleanup routines of some user defined types of which you create instances inside the main function. Try setting breakpoints inside the destructors of your own classes and investigate.
It is possible that you are corrupting the heap during the program operation, but it is not being detected until the end of the program, in which case the stack trace would only point to the memory checking routine
There may be a function you can call during operation that checks if the heap is valid, which may bring the fail closer to the point of corruption
HeapValidate is an example of such a routine, but it would depend on what platform you are using
This error can also happen when you use delete[] instead of delete. However, as mentioned, this is only one of many causes.

Freeing a null pointer causes following pop up message

I have some memory intensive code followed by the following statement
free(array1); // array1 is NULL
I essentially called free upon a null pointer. It was my understanding that accidentally calling free on a NULL pointer was safe. However, I got the following pop up when the free statement was executed.
"Windows has triggered a breakpoint in app.exe.
This may be due to a corruption of the heap, which indicates a bug in app.exe or any of the DLLs it has loaded."
Does this mean free is not safe to call on NULL pointers, or is this a sign that there could be memory problems in my program?
When I uncomment the free statement, everything works normally.
It is definitely safe to call free() on a NULL pointer, so you must have corrupted your heap earlier. That said, it may be worth putting a print statement in to guarantee array1 really is NULL just before the crash. If you can't spot the error, you may have to resort to tools to help you - there are lots of questions about such heap usage verification tools.
Supporting docs: you're on Windows, but the API is the standardised with the C language: see "If ptr is NULL, no operation is performed." at http://linux.die.net/man/3/free
Of course, you should check new/new[]/malloc-or-realloc are properly paired with delete/delete[]/realloc-or-free everywhere. There are valid reasons to be using malloc/free in C++ though - most obviously for interoperability with C code, and very occasionally for the potential performance benefits of in-place growth with realloc.
"When I uncomment the free statement, everything works normally." - best not to rely on that... if your program misuses the heap, it could crash at any time e.g. some runs and not others, after the tiniest seemingly unrelated change anywhere in your code, after changing a compiler flag, with innocuous input changes, or even the same executable deployed on another PC....

Memory failures when calling new

It might be a little hard to explain everything about this error but I'll try my best. Unfortunately the code is so large that it would be unpractical to try to include it.
I am writing an academic OS for homework (nachos if you must know) and the most recent thing I needed to do was implement mutual exclusion in a core map. To do this I added a Lock and a condition variable per page in emulated main memory. After doing this I run my code and get through one call to the exception (in a completely different directory from core map) handler just fine, but the second time the function gets called I get and error on the following call: r=new Lock("read"); and it reads like this:
*** glibc detected *** /home/some_other_directories/workspace/nachos3_repo/vm/nachos: malloc(): memory corruption (fast): 0x0805fe20 ***
Just to see how it behaves I changed the allocation of that lock to be an extern in my system file (there are a lot of global externs there) and after that I get a seg fault on the call fout.open("old.txt"); which I traced back through the stack to be within a call to malloc in a call to new.
My best guess is that my heap is getting to large but I am not sure if that is the case or how to handle it if it is. can anyone shed light on this problem?
malloc is just the victim here. In some completely different part of the code you have written outside the allocated boundaries and thus have corrupted chain links that are used by the heap manager to track free/allocated blocks. As you try to allocate here, the heap manager is chasing these linked lists and lands into a protected area (most likely not allocated). You should do a review of your changes first and see if you can spot where you scribble the memory.

I get an exception if I leave the program running for a while

Platform : Win32
Language : C++
I get an error if I leave the program running for a while (~10 min).
Unhandled exception at 0x10003fe2 in ImportTest.exe: 0xC0000005: Access violation reading location 0x003b1000.
I think it could be a memory leak but I don't know how to find that out.
Im also unable to 'free()' memory because it always causes (maybe i shouldn't be using free() on variables) :
Unhandled exception at 0x76e81f70 in ImportTest.exe: 0xC0000005: Access violation reading location 0x0fffffff.
at that stage the program isn't doing anything and it is just waiting for user input
dllHandle = LoadLibrary(L"miniFMOD.dll");
playSongPtr = (playSongT)GetProcAddress(dllHandle,"SongPlay");
loadSongPtr = (loadSongT)GetProcAddress(dllHandle,"SongLoadFromFile");
int songHandle = loadSongPtr("FILE_PATH");
// ... {just output , couldn't cause errors}
playSongPtr(songHandle);
getch(); // that is where it causes an error if i leave it running for a while
Edit 2:
playSongPtr(); causes the problem. but i don't know how to fix it
I think it's pretty clear that your program has a bug. If you don't know where to start looking, a useful technique is "divide and conquer".
Start with your program in a state where you can cause the exception to happen. Eliminate half your code, and try again. If the exception still happens, then you've got half as much code to look through. If the exception doesn't happen, then it might have been related to the code you just removed.
Repeat the above until you isolate the problem.
Update: You say "at that stage the program isn't doing anything" but clearly it is doing something (otherwise it wouldn't crash). Is your program a console mode program? If so, what function are you using to wait for user input? If not, then is it a GUI mode program? Have you opened a dialog box and are waiting for something to happen? Have you got any Windows timers running? Any threads?
Update 2: In light of the small snippet of code you posted, I'm pretty sure that if you try to remove the call to the playSongPtr(songHandle) function, then your problem is likely to go away. You will have to investigate what the requirements are for "miniFMOD.dll". For example, that DLL might assume that it's running in a GUI environment instead of a console program, and may do things that don't necessarily work in console mode. Also, in order to do anything in the background (including playing a song), that DLL probably needs to create a thread to periodically load the next bit of the song and queue it in the play buffer. You can check the number of threads being created by your program in Task Manager (or better, Process Explorer). If it's more than one, then there are other things going on that you aren't directly controlling.
The error tells you that memory is accessed which you have not allocated at the moment. It could be a pointer error like dereferencing NULL. Another possibility is that you use memory after you freed it.
The first step would be to check your code for NULL reference checks, i.e. make sure you have a valid pointer before you use it, and to check the lifecycle of all allocated and freed resources. Writing NULL's over references you just freed might help find the problem spot.
I doubt this particular problem is a memory leak; the problem is dereferencing a pointer that does not point to something useful. To check for a memory leak, watch your process in your operating system's process list tool (task manager, ps, whatever) and see if the "used memory" value keeps growing.
On calling free: You should call free() once and only once on the non-null values returned from malloc(), calloc() or strdup(). Calling free() less than once will lead to a memory leak. Calling free() more than once will lead to memory corruption.
You should get a stack trace to see what is going on when the process crashes. Based on my reading of the addresses involved you probably have a stack overflow or have an incorrect pointer calculation using a stack address (in C/C++ terms: an "auto" variable.) A stack trace will tell you how you got to the point where it crashed.