What prevents an exception from being caught? - c++

I have a Win32 C++ app developed in VS2005. There is a try {} catch (...) {} wrapped around a block of code, and yet 3 functions deep, when the algorithm breaks down and tries to reference off the end of a std::vector, instead of catching the exception, the program drops into the VS debugger, tells me I have an unhandled win32 exception, and the following is found on the call stack above my function:
msvcr80.dll!:inavlid_parameter_noinfo()
msvcr80.dll!:invoke_watson(....)
msvcr80.dll!:_crt_debugger_hook(...)
How can I prevent the debugger being called? This occurs at the end of a 30 minute simulation, at which point I lose all my results unless I can catch and log the exception. This and similar try/catch constructs have been working in the past - are there compiler settings which affect this? Help?

You may want to convert non-C++ exceptions into C++ exceptions. Here's an example of how to do it.

Apologies for the delay - unforeseen circumstances - but the real answer appears to be the following.
First, the application is also wrapped in a __try {} __except () {} construct, and uses unhandled exception filtering based on XCrashReport. This picks up the non C++ exceptions for the reasons many have pointed out above.
Second, however, as one can find here and elsewhere, since CRT 8.0, for security reasons Microsoft bypasses unhandled exception handling on buffer overruns (and certain other situations), and passes the issue directly to Dr Watson.
This is really annoying - I want to know where my buffer overruns are occurring, and why, and to fix them. I also want my program to crash, leave an audit trail, and then be automatically restarted, 24/7. Having MS Visual Studio on the PC seems to mean that Dr Watson will pause and offer me the option of using MSVC to debug the issue. However, until I respond to the dialog box, nothing will happen. Comments on workarounds greatly appreciated...

Just because you have a catch(...) doesn't mean you can catch and recover from all exceptions. Not all exceptions are recoverable.
You problem might be that the first exception that pin points the exact problem is getting obscured by your catch statement
You need to attach the debugger to the program and have it break on all exceptions and fix the code

Standard Library containers do not check for any logic errors and hence themselves never emit any exceptions.
Specifically, for std::vector only method that throws an exception is std::vector::at().
Any Undefined Behavior w.r.t to them will most likely lead your program to crash.
You will need to use Windows' SEH and C++ Exception Handling for catching Windows specific exceptions, which are non C++ standard btw.

Related

How do you debug MinGW exception handling?

I have an utterly baffling problem with a C++ program I'm compiling with MinGW. At a certain, deterministic point in the program some exception handlers get disabled, and any future exceptions thrown are no longer handled. I can track down the precise line of source that does this, it's an inoffensive assignment to an array on the heap. The pointer isn't corrupt, nor am I writing beyond its bounds. What's more the same code is called in a bunch of different circumstances, even with most of the same arguments without triggering the bug. If I fiddle with the code to make the value it writes always zero, the bug is never triggered. I'm at a loss to know what's happening. It also only disables some exception handlers. exception handlers further down the callstack get disabled, while ones higher up stay active. It's baffling.
So, how do should I go about debugging this? I really don't have a good grasp of how exceptions actually work in MinGW's version of GCC. What could be happening to cause this weird set of symptoms?
Never mind, turns out that taking some time out and thinking about the symptoms suggested the answer.
Turns out a terrible library I'm using can throw an exception during cleanup, so I was getting an exception within an exception during stack unwinding.
I should have realised that when handlers further up the call stack behaved properly. Duh.

Can I get a stack trace for un-handled (Objective) C++ exceptions?

I'm developing an iOS application that has recently grown a large C++ base. C++ is not my forte, and I'm getting frustrated by exceptions. What I'm looking for is a way to get a stack track to the site of an (un-handled) exception throw. I'll say that the "un-handled" qualifier is optional; I would settle for breaking on any exception throw as a last resort, though un-handled exceptions are ideal.
What I currently get is useless. Assuming I don't have any appropriate exception handlers higher up the callstack, and I do something like
std::vector<int> my_vector;
my_vector.at(40) = 2; // Throws std::out_of_range
The app will break in main() and I'll get a log message saying "terminate called throwing an exception." Not helpful.
Putting generic try/catch blocks higher up the callstack doesn't help either, because the callstack is unwound during exception handling up to the point of the catch block, leaving me ignorant to actual origin of the exception. This also applies to providing my own terminate_handler. Asserts are more useful, but they require me to anticipate error conditions to some extent, which I cannot always do. I would still like the debugger to be able to step in even if an unexpected exception makes it past my pre-emptive assert()s.
What I want to avoid is having to wrap every call that might possibly throw an exception in a try/catch block just to get the stack trace to the error. At runtime, I'm really not interested in catching these exceptions. When they occur, it means there's a fatal flaw in the program execution, and there's no way it can continue normally. I just want to be notified so I can determine the cause and mend the issue so it won't happen again.
In Objective C, I can put a symbolic breakpoint on objc_exception_throw, and any time I screw something up I'll immediately break execution and be presented with a nice stack trace so I know where the issue is. Very helpful.
I realize this behavior is really only useful because of a philosophical difference in exception handling between the two languages. Objective C exceptions are intended only to signify unrecoverable errors. The task of routine error handling is accomplished via error return codes. This means that any Objective C exception is a great candidate for a breakpoint to the developer.
C++ seems to have a different use for Exceptions. They're used to handle both fatal errors and routine errors (at least in the 3rd party libs I'm using). This means I might not actually want to break on every exception that's thrown in C++, but I would still find the ability useful if I can't break only on un-handled exceptions.
You can quickly establish a break on all C++ throw conditions in Xcode:
cmd+6
"+" button -> Add Exception Breakpoint
C++ -> std::out_of_range
On Throw
Update
If you have a lot of them tho filter out, you may prefer to:
Create a Symbolic Breakpoint
Symbol = __cxa_throw (may vary by std library)
Action > Debugger Command = bt
Automatically continue after eval = On
The bt command logs the backtrace. Configured this way, it will automatically continue.
So, this will just log the backtrace of every thrown exception - when your program terminates due to an unhandled exception, the clues will be among the final logged backtraces (often the last, unless the library rethrows).
In the app I get to debug with many c++ exceptions, I leave the "Catch C++ Exceptions on Throw" off until I get to the point in the app where it will throw the exception, then I turn that option on and usually the next exception that is thrown is what I'm looking for. This will break a few levels deeper than where the error is, but the stack is intact so you can figure out what is going on.
Check PLCrashReporter. We use it with our application (which relies heavily on C++) and it produces stack traces even for the C++ code.
The only problem you might have is when using assembly routines which were not written natively for iOS (Apple's compiler is using R7 to hold the stack frame for tracing back symbols which is not according to official ARM EBI)

Why won't my code segfault on Windows 7?

This is an unusual question to ask but here goes:
In my code, I accidentally dereference NULL somewhere. But instead of the application crashing with a segfault, it seems to stop execution of the current function and just return control back to the UI. This makes debugging difficult because I would normally like to be alerted to the crash so I can attach a debugger.
What could be causing this?
Specifically, my code is an ODBC Driver (ie. a DLL). My test application is ODBC Test (odbct32w.exe) which allows me to explicitly call the ODBC API functions in my DLL. When I call one of the functions which has a known segfault, instead of crashing the application, ODBC Test simply returns control to the UI without printing the result of the function call. I can then call any function in my driver again.
I do know that technically the application calls the ODBC driver manager which loads and calls the functions in my driver. But that is beside the point as my segfault (or whatever is happening) causes the driver manager function to not return either (as evidenced by the application not printing a result).
One of my co-workers with a similar machine experiences this same problem while another does not but we have not been able to determine any specific differences.
Windows has non-portable language extensions (known as "SEH") which allow you to catch page faults and segmentation violations as exceptions.
There are parts of the OS libraries (particularly inside the OS code that processes some window messages, if I remember correctly) which have a __try block and will make your code continue to run even in the face of such catastrophic errors. Likely you are being called inside one of these __try blocks. Sad but true.
Check out this blog post, for example: The case of the disappearing OnLoad exception – user-mode callback exceptions in x64
Update:
I find it kind of weird the kind of ideas that are being attributed to me in the comments. For the record:
I did not claim that SEH itself is bad.I said that it is "non-portable", which is true. I also claimed that using SEH to ignore STATUS_ACCESS_VIOLATION in user mode code is "sad". I stand by this. I should hope that I had the nerve to do this in new code and you were reviewing my code that you would yell at me, just as if I wrote catch (...) { /* Ignore this! */ }. It's a bad idea. It's especially bad for access violation because getting an AV typically means your process is in a bad state, and you shouldn't continue execution.
I did not argue that the existence of SEH means that you must swallow all errors.Of course SEH is a general mechanism and not to blame for every idiotic use of it. What I said was that some Windows binaries swallow STATUS_ACCESS_VIOLATION when calling into a function pointer, a true and observable fact, and that this is less than pretty. Note that they may have historical reasons or extenuating circumstances to justify this. Hence "sad but true."
I did not inject any "Windows vs. Unix" rhetoric here. A bad idea is a bad idea on any platform. Trying to recover from SIGSEGV on a Unix-type OS would be equally sketchy.
Dereferencing NULL pointer is an undefined behavior, which can produce almost anything -- a seg.fault, a letter to IRS, or a post to stackoverflow :)
Windows 7 also have its Fault Tollerant Heap (FTH) which sometimes does such things. In my case it was also a NULL-dereference. If you develop on Windows 7 you really want to turn it off!
What is Windows 7's Fault Tolerant Heap?
http://msdn.microsoft.com/en-us/library/dd744764%28v=vs.85%29.aspx
Read about the different kinds of exception handlers here -- they don't catch the same kind of exceptions.
Attach your debugger to all the apps that might call your dll, turn on the feature to break when an excption is thrown not just unhandled in the [debug]|[exceptions] menu.
ODBC is most (if not all) COM as such unhandled exceptions will cause issues, which could appear as exiting the ODBC function strangely or as bad as it hang and never return.

Unhandled Win32 exception

At runtime, when myApp.exe crashes i receive "Unhandled Win32 exception" but how would i know which exception was occurred? where did something went wrong?
For a Native C++ app see my earlier answer here: Detect/Redirect core dumps (when a software crashes) on Windows for catching the unhandled exception (that also gives code for creating a crash dump that you can use to analyse the crash later. If the crash is happening on a development system then in Visual Studio (I'm assuming you're using that, if not other IDEs will have something similar), in Debug/Exceptions tick the 'Thrown' box for 'Win32 Exceptions'.
Typically, Windows will give you several hexadecimal numbers as well. Chances are that the exception code will be 0xC0000005. This is the code of an Access Violation. When that happens, you also will have three additional bits of information: the violating address, the violated address, and the type of violation (read, write or execute).
Windows won't narrow it down any further than that, and often it couldn't anyway. For instance, if you walk past the end of an array in your program, Windows likely won't realize that you were even iterating over an array. It just sees "read:OK, read:OK, read:out of bounds => page fault => ACCESS VIOLATION". You will have to figure that out from the violating address (your array iteration code) and the violated address (the out-of-bounds address behind your array).
If it's a .Net app you could try to put in a handledr for the UnhandledException event. You can find more information about it and some sample code here.
In general it's a good sign that your exception handling is broken though, so might be worth going through your code and finding places that could throw but where you don't handle exceptions.
Use the debugger. You can run the program and see what exception is been thrown that kills your application. It might be able to pinpoint the location of the throw. I have not used the VS debugger for this, but in gdb you can use catch throw to force a breakpoint when an exception is thrown, there should be something similar.

run-time error and program crash

How can I specify a separate function which will be called automatically at Run-Time error to prevent program crash?
Best thing as mentioned already is to identify the area where the crash ic occuring and then fix the piece of code. This is the idealistic approach.
In case you are unable to find that out another alternative is to do structured exception handling in the areas where you suspect crashes to occur. Once the crash occurs you capture what ever data you want and process it. Meanwhile you can change the settings in windows service manager to restart your application whenever it crashes. Hope this answers your question.
Also in case you are looking for methods to capture the crash and analyse debugdiag and windbg are some of the standard tools that people use to take the crash dumps.
If your in Windows you need to write your own custom runtime check handler. Use:
_RTC_SetErrorFunc
to install your custom function in place of
_CrtDbgReport.
Here is a good article on how to do it:
http://msdn.microsoft.com/en-us/library/40ky6s47(VS.71).aspx
If by run-time error you mean an unhandled exception, don't do it. If an unhanded exception propagates through your code, you want your app to crash. Maybe create a dumpfile on the way down, sure. But the last thing you want to do is catch the exception, do nothing, and continue running as if nothing had happened in the first place.
When an exception is generated, whatever caused the problem could have had other effects. Like blowing the stack or corrupting the heap. If you were to silently ignore these exceptions and continue running anyway, your app might run for a while and seem OK, but something underneath is unstable. Memory could be corrupt, resources might not be available, who knows. You will eventually crash. Bu ignoring unhandled exceptions and running anyway, all you do is delay the inevitable, and make it that much more difficult to diagnose the real problem, because when you do crash, the stack will be in a totally different and probably unrelated place from what caused the initial problem.