what happens when routine "free" fails in a "try" block in c++ - c++

Typically, if memory issue occurred in calling routine "free", a program will stop immediately with error message telling details of the error. Now assume "free" is called in a "try" block. If an error occurred with the call, will the program stop immediately with an error message, or will the program completes execution of the "try" block before exiting with error message?

free can't error out without some preexisting problem in your code occurring, almost certainly a result of undefined behavior. Once you're in the land of nasal demons, there are no guarantees. free doesn't have a concept of exceptions (it's a C function, no C++ features), or even error return codes; if you corrupt your heap, the program is already screwed, and what comes next can be anything. In practice, I'd expect one of four possibilities:
free doesn't notice the corrupted heap, and just makes things worse silently (try block continues running, because it doesn't realize anything is wrong)
free notices the corrupted heap, and the program dies immediately (no try/catch handling)
free is operating on a pointer to an invalid/unallocated region of memory, and you die with a segfault, bus error, etc. (again, no try/catch handling)
The pointer is to allocated memory that's not part of the heap; behaves like #1 or #2 depending on how "heap-like" it happens to look to the code.

Related

How to find reason for app crash on close?

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.

Assert frees memory in C++

Suppose we have a program where we allocate some memory and then we have an assert statement some lines after. If the assert statement throws and error, what happens with the allocated memory? Does it get free before stopping the program?
assert on failure, writes the error to stderr and calls abort(). which unlike exit() doesn't execute the functions registered with atexit(), nor does it call destructors.
Hence, none of your destructors, clean-up code etc can be called. So it is up to the OS, as the memory isn't freed by the program, before its "unexpected" termination.
This is probably by design, as calling destructors might result in some further error. It terminates at that failed assert, executing no further code.
The memory stays allocated as the assert failure brings down your program.
As part of destroying the process, any modern desktop OS will reclaim the memory. Some embedded operating systems might not be able to do this, although I don't have the name of one on hand.
You can detect memory that has to be reclaimed by the OS this way by using a utility such as Valgrind.

Is this considered memory leak?

The general rule, only objects allocated in the free store can cause memory leaks.
But objects created in the stack doesn't.
Here is my doubt,
int main()
{
myclass x;
...
throw;
...
}
If throw is not handled, it calls, terminate(), which in turn calls abort() and crashes the application. At this time, the objects in the stack are not destoryed (The destructor is not invoked).
My understanding is "When the application terminates (either by abort or by normal exit), it frees all the memory that was allocated for the application". Thus this cannot be considered as memory leak.
Am I correct?
In a hosted environment (e.g. your typical Unix / Windows / Mac OS X, even DOS, machine) when the application terminates all the memory it occupied is automatically reclaimed by the operating system. Therefore, it doesn't make sense to worry about such memory leaks.
In some cases, before an application terminates, you may want to release all the dynamic memory you allocated in order to detect potential memory leaks through a leak detector, like valgrind. However, even in such a case, the example you describe wouldn't be considered a memory leak.
In general, failing to call a destructor is not the same as causing a memory leak. Memory leaks stem from memory allocated on the heap (with new or malloc or container allocators). Memory allocated on the stack is automatically reclaimed when the stack is unwound. However, if an object holds some other resource (say a file or a window handle), failing to call its destructor will call a resource leak, which can also be a problem. Again, modern OSs will reclaim their resources when an application terminates.
edit: as mentioned by GMan, "throw;" re-throws a previously thrown exception, or if there is none, immediately terminates. Since there is none in this case, immediate termination is the result.
Terminating a process always cleans up any leftover userland memory in any modern OS, so is not typically considered a "memory leak", which is defined as unreferenced memory not deallocated in a running process. However, it's really up to the OS as to whether such a thing is considered a "memory leak".
The answer is, it depends on the OS. I can't think of a modern OS that does not do it this way. But old systems (I think up to win 3.1 in windows, and some old embedded Linux platforms) if the program closed without releasing its memory requests the OS would hold them until you rebooted.
Memory leaks are considered a problem because a long running application will slowly bleed away system memory and may in the worst case make the whole machine unusable due to low memory conditions. In your case, the application terminates and all memory allocated to the application will be given back to the system, so hardly a problem.
The real question is, "Does myclass allocate any memory itself that must be free/deleted?"
If it does not -- if the only memory it uses is it's internal members -- then it exists entirely on the stack. Once it leaves that function (however it does), the memory on the stack is reclaimed and reused. myclass is gone. That's just the way stacks work.
If myclass does allocate memory that needs to be freed in it's dtor, then you are still in luck, as the dtor will be called as the stack is unwound during the throw. The dtor will have already been called before the exception is declared unhandled and terminate is called.
The only place you will have a problem is if myclass has a dtor, and the dtor throws as exception of it own. The second throw occurring during the stack unwind from the first throw will have it call terminate immedaitely without any more dtors being called.
From OP,
If throw is not handled, it calls,
terminate(), which in turn calls
abort() and crashes the application.
At this time, the objects in the stack
are not destoryed (The destructor is
not invoked).
This is an implementation defined behavior.
$15.3/9- "If no matching handler is
found in a program, the function
terminate() is called; whether or not
the stack is unwound before this call
to terminate() is
implementation-defined (15.5.1)."
Therefore, whether this constitues a memory leak or not is also implementation defined behavior, I guess.
My understanding is "When the application terminates (either by abort or by normal exit), it frees all the memory that was allocated for the application". Thus this cannot be considered as memory leak.
Am I correct?
Memory leak is a type of programming error which is ranked somewhat lower on scale of programming errors - compared to the uncaught exception.
IOW, if program doesn't terminate properly, a.k.a. crashes, then it is too soon to speak about memory leaks.
On other note, most memory analyzers I have worked with over past decade would not trigger any memory leak alarm in the case - because they do not trigger any alarms when program dumbly crashes. One first has to make program not crashing, only then debug the memory leaks.

buffer overrun throw return address

When I throw in a method A, it causes buffer overrun but when I return, it runs fine.
I thought throw moves execution to the caller method so the address it goes to should be the same as return address, but i am obviuosly wrong.
Is there a way to see what address throw goes to in Visual Studio debugger?
Thank you
Berkus:
does this mean that stack of upper caller method is corrupted? So for example,
Method A calls
Method B calls
Method C. Method C throws an exception
Then, it is possible that Method C's return address is ok but Method B's return address is corrupted, causing buffer overrun? What I am seeing is that if there is no throw, my application runs fine, so I think Method A,B and C all have valid return addresses.
Throw will unwind the stack, until it reaches the function with catch in it. The return address does not matter, as throw can go up several levels of stack frames if necessary.
In C++, if you have no try/catch block then this:
Method A calls
Method B calls
Method C. Method C throws an exception
will terminate the application. You must have a try/catch block in your code if want to avoid termination.
Exactly how return addresses and thrown exceptions interact is left to the details of how your particular compiler implements exception handling. To say anything about it with much certainty, someone here would have to be familiar with those internal details.
It's certainly conceivable that a buffer overrun could corrupt data that is only used by the exception handling (thus causing a throw to fail) while leaving the return address intact (thus allowing a normal return to succeed). But again, that depends on how your compiler is making use of the stack. (On a different compiler you might get totally different symptoms). It's also possible that the corruption has caused other problems that you simply haven't noticed yet. Or that such corruption will cause problems in the future after the next time you change your code. If the stack (or other memory that C++ depends on) becomes corrupted, then just about anything could happen.
Wither some educated guess-work or knowledge of the compiler details, I'm sure someone could eventually answer the specific questions about return addresses and how throwing works. However, I really think these are the wrong questions to be asking.
If you actually know you have a buffer overrun, then there's no point in trying to answer these questions. Just fix the overrun.
If you only suspect you have an overrun or are trying to track down how it's happening, then try stepping through your code in the debugger and watch for changes to memory outside the bounds of your variables. Or perhaps, alter your function to always throw and then start commenting out suspicious parts of your process one by one. Once the throw starts working again, you can then take a closer look at the code you last commented since the problem is most likely there. If these suggestions don't help, then I think the real question to ask here is "How do I track down memory corruption that only affects throwing an exception?".

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.