How to build a C++ Dll wrapper that catches all exceptions? - c++

Like the title says, we’re looking for a way to catch all exceptions from a piece of C++ code, and wrap this in a dll. This way we can shield of the application that uses this dll, from any errors occurring in this dll.
However, this does not seem possible with C++ under Windows.
Example:
void function()
{
try
{
std::list<int>::iterator fd_it;
fd_it++;
} catch(...) {}
}
The exception that occurs is not caught by the standard C++ try/catch block, nor by any SEH translator function set by _set_se_translator(). Instead, the DLL crashes, and the program that uses the DLL is aborted. We compiled with Visual C++ 2005, with the option /SHa. Does anyone know if it’s possible in C++/Win32 to catch these kind of problems and make a rocksolid DLL wrapper?

The only way to make a rock solid DLL wrapper is to load the buggy DLL in another process, so that if it crashes it doesn't take your primary process down with it.
Catching all C++ exceptions seems reasonable, but catching all structured exceptions is another story. SEH might seem to get you most of the way there, because it allows you to catch access violations, divide-by-zero exceptions, etc.
But what if the buggy DLL happens to touch an uncommitted page from another thread's stack? The memory access will page fault, the exception handler will be invoked, and now that page is no longer a guard page. When that thread needs to grow the stack, it will get an access violation, and the process will crash. (These posts describe this case in more detail.)
Another likely problem: the buggy DLL crashes while holding a synchronization object, but you use SEH to catch the exception. If your process attempts to acquire the same synchronization object, then it deadlocks instead of crashing. The shared synchronization object may be part of the C runtime or the OS: what if buggy DLL 1 loads buggy DLL 2, which crashes in its DllMain() while buggy DLL 1 is holding the loader lock? Will your process deadlock the next time it loads a DLL?
For more information on why this (and functions like IsBadReadPtr(), which have similar problems) is a misuse of SEH:
Larry Osterman's WebLog: Structured Exception Handling Considered Harmful
Larry Osterman's WebLog: Should I check the parameters to my function?
Larry Osterman's WebLog: Resilience is NOT necessarily a good thing
The Old New Thing: IsBadXxxPtr should really be called CrashProgramRandomly

On Windows, C++ has 2 different styles of exceptions: C++ and SEH exceptions.
SEH is a windows only form of exceptions (somewhat akin to signals in UNIX). It's more of a system level exception. They will be thrown for such operations as invalid pointer accesses, alignment issues, etc ...
If you want to catch every exception that can be thrown by a C++ app on windows you will need to catch both. Fortunately there is a way to mix the use of C++ and SEH exceptions. I wrote a detailed blog post about this recently, it should help you out.
http://blogs.msdn.com/jaredpar/archive/2008/01/11/mixing-seh-and-c-exceptions.aspx

Incrementing an iterator on a standard libary container will never throw a C++ exception. It may give you undefined behaviour.

The code below is taken from the Zeus IDE. It will trap any Windows generated exceptions:
Step #1: Define an Exception Filter Function
DWORD ExceptionFilter(EXCEPTION_POINTERS *pointers, DWORD dwException)
{
//-- we handle all exceptions
DWORD dwResult = EXCEPTION_EXECUTE_HANDLER;
switch (dwException)
{
case EXCEPTION_ACCESS_VIOLATION:
case EXCEPTION_DATATYPE_MISALIGNMENT:
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
case EXCEPTION_FLT_DENORMAL_OPERAND:
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
case EXCEPTION_FLT_INEXACT_RESULT:
case EXCEPTION_FLT_INVALID_OPERATION:
case EXCEPTION_FLT_OVERFLOW:
case EXCEPTION_FLT_STACK_CHECK:
case EXCEPTION_FLT_UNDERFLOW:
case EXCEPTION_INT_DIVIDE_BY_ZERO:
case EXCEPTION_INT_OVERFLOW:
case EXCEPTION_PRIV_INSTRUCTION:
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
case EXCEPTION_BREAKPOINT:
dwResult = EXCEPTION_EXECUTE_HANDLER;
break;
}
return dwResult;
}
Step #2: Wrap the code in a __try and __except as shown below:
__try
{
// call your dll entry point here
}
__except(ExceptionFilter(GetExceptionInformation(),
GetExceptionCode()))
{
//-- display the fatal error message
MessageBox(0, "An unexpected error was caught here!",
"Unexpected Error", MB_OK);
}

Konrad Rudolph: Of course this code contains a "logic error", it's to illustrate a problem that could occur. Like the man says he wants to be able to shield his dll from any possible errors. You don't think this is a legitimate question? Heard of vendor products. Some of us live in the real world and live with real problems. It's just not possible to fix everyone else's problems

This code contains a logic error, if at all. Since a logic error constitues a bug, don't swallow the exception – fix the error!
Of course, this is specific to the particular code. Others have offered more general advice. However, I've found that a lot of people actually do prefer catching exceptions over fixing logic errors and this is simply unacceptable.

Have you looked at the windows API function SetUnhandledExceptionFilter?
I usually call it in the DllMain function and have it generate a minidump when the DLL crashes. However: (a) I don't know if it traps application exceptions as well as DLL exceptions, and (b) I don't know if you can have the handler return in such a way that program execution can continue. The docs say yes, but I've never done it.

What are you going to do after you catch the exception (especially for SEH exceptions)?
In reality you can make no assumptions about the state of the process, realistically the only option you have is to (optionally) dump core and exit.
Any attempt and proceeding is absolutely going to cause you problems in the long run.

Related

MS Visual Studio 2005 C++ exception handling

I have a C++ application built in MS Visual Studio 2005 that links to a 3rd party library. For a certain input, the application crashes in the 3rd party library (apparently somewhere in realloc.c; so has to be a memory issue of some kind). I ran in release because the input is huge. So I ran until it crashes and then choose to debug. While I separately debug the guilty function, I was hoping to use some exception handling to prevent the application from crashing and instead exit cleanly. So I used something like:
try {
//- call 3rd party application function that fails
}
catch(...) {
//- handle exception or whatever
Logger::Fatal("Fatal error: Exiting...");
return false;
}
But to my surprise the application still crashes! I was expecting to see it display the error message since I've presumably caught all exceptions with the ellipsis (...); what am I missing here? I even tried setting /EHca (was /EHsc) in Project Properties -> C/C++ -> Code Configuration -> Enable Exception Handling. On a related note about what might be causing the problem, is the following usage correct?
my_class* mc[] = {nil, nil, nil};
for (int i = 0; i < 3; ++i) {
mc[i] = new my_class();
//-Do stuff with mc[i]
if (mc[i] != nil) {
delete mc[i];
mc[i] = nil;
}
}
The failure to get the exception handling working is rather puzzling. I would certainly appreciate ideas/insights from the C++ gurus out there. BTW, the same problem also occurs on Linux (RHEL5) but I am currently trying to get the exception handling to work on Windows.
NOTE: When I let it debug after the crash. I do get an "Access violation..unable to read location" message. With this updated info, I was hoping something in C++ would still work on both Windows & Linux for such crashes.
Have you tried catching the crash by calling SetUnhandledExceptionFilter?
As Miguel suggested, a correct way to solve your problem is probably to use SetUnhandledExceptionFilter. But I'd like to explain your phenomena in details nevertheless.
First of all, not all the program "crashes" are related to exceptions. For instance, CRT may trigger program termination upon errors, such as invalid element access in a vector, or a pure virtual destructor call. If you want to cover those cases as well - see set_unexpected, set_terminate and etc.
Besides of this, catch block may only catch exceptions thrown from the appropriate code block. OTOH there may be functions that are called elsewhere, such as window procedures (if applicable), other threads and etc.
Now, regarding your problem. Let's first realize why things like catch(...) may catch things like access violation, and etc, and why this does not always happen (like in your case).
Windows provides its own exception handling mechanism - SEH, structured exception handling. It's far superior to C++ exception handling. In addition hardware interrupts (caused by CPU) are automatically "converted" into SEH exceptions, so that the code that uses SEH handles both software exceptions and hardware failures.
Microsoft C++ compilers actually implement C++ exceptions via SEH. That is throw is implemented via RaiseException with specifying C++ - specific exception code and parameters, catch is a C++ - specific wrapper for __except, and for every object with destructor the compiler generates something similar to __finally block. And this also works vice-versa. When a non-C++ exception is raised - the same code generated for C++ exceptions is executed.
In addition there are so-called compiler exception handling options that affect both the compiler exception handling code generation, and its behavior in runtime. They are called exception handling models:
synchronous. The compiler generates a code that is guaranteed to work correctly only if exceptions are raised explicitly. This includes throw statments, and all the "foreign" functions whose code is not visible to the compiler (in some variations - only C++ foreign functions). In particular reading from memory is considered "safe".
asynchronous. The compiler is not allowed to assume anything about where exceptions may arise. Hence it generates the code that should work correctly even if exception is arises from accessing a memory address.
In addition, CRT code that's invoked in catch (...) deliberately ignores non-C++ exceptions, unless asynchronous EH model is choosen.
So that if you want catch (...) to catch non-C++ exceptions - you must choose the asynchronous EH model.
Once I've written an article on the codeproject, after I had a related problem in driver development. It explains all this in details.

Programmatically catching windows close event when out of GDI resources

I'm trying to catch all unexpected terminations in my process.
I've used these functions to catch all the unhandled errors and exceptions that i can think of, but still it's not enough:
SetUnhandledExceptionFilter(OnUnhandledNativeException);
set_terminate(set_terminateHandler);
set_unexpected(set_unexpectedHandler);
_set_purecall_handler(set_purecallHandler);
_set_new_handler(HandleProgramMemoryDepletion);
_set_invalid_parameter_handler(InvalidParameterHandler);
signal(SIGABRT, sigabrt_handler);
signal(SIGINT, sigabrt_handler);
signal(SIGTERM , sigabrt_handler);
These functions catch almost any error in the application.
But, when the application is terminated because of a GDI failure (for example GDI out of resources), non of these functions are called.
Does anyone know how i can catch GDI error events ?
I'm sure there must be some way to overload it and change the callback function.
And, does anyone know of any other weird scenarios where these functions just aren't enough ?
Note:
The exact error that it's not catching is "A required resource was unavailable".
This is caused when you create a lot of GDI objects and don't release them.
The program will crash because there aren't enough resources long before it runs out of memory.
Some of the functions you listed (e.g. SetUnhandledExceptionFilter) set the handlers for the current thread. Therefore you should call them in each thread.
You can add Vectored Exception Handling to the list (AddVectoredExceptionHandler).
If you're on Visual C++ __try __finally will usually do the trick. Note that this is not a portable solution.
Ok, solved the problem.
It WAS catching the crash.
The problem was that as part of the process of salvaging the data from the crash, it was opening a Form which was supposed to notify the user that an error has occurred.
Of course, we're out of GDI objects, so the Form can't be drawn, so that in itself threw and exception, we had another unhandled exception, and the process really crashed.

Convert std::exception to EXCEPTION_POINTERS

I may be completely misunderstanding how to use the Google Breakpad API, and am open to comments / suggestions / rude remarks if that is the case. I am trying to call the following C++ function:
bool WriteMinidumpForException(EXCEPTION_POINTERS* exinfo);
I have a reference to a std::exception:
try {
return QApplication::notify(receiver, event);
} catch (std::exception &ex) {
eh_.WriteMinidumpForException(?????);
// ... do some more stuff and ultimately kill this process
}
(eh_ is a google_breakpad::ExceptionHandler.)
What do I put in the ?????
Background: The reason this is necessary (I think) is that Qt will not support an exception thrown in an event handler. It will not propagate correctly, and thus the minidump that Breakpad produces is completely useless because the actual context of the exception has been lost. Instead, you must catch all exceptions and handle them in the override of QApplication::notify(), which is what I am trying to do. In the case of an exception, I want to immediately write my minidump for that exception (which is sounds like WriteMinidumpForException will do) and then notify the user and quit the application. But I am not sure what to pass as the EXCEPTION_POINTERS* parameter.
In the MSVC compiler, C++ exceptions piggy-back onto the native Windows exception plumbing (SEH, Structured Exception Handling). There's a pretty big impedance mismatch though, the concept of an exception filter is doesn't have a good match in C++. By the time the catch handler catches an exception, the SEH exception is already handled and the stack unwound. The EXCEPTION_POINTERS info is gonzo. The exception filters actually exist, that's how it filters for the specific type you want to catch, they are however auto-generated by the compiler. No reasonable C++ syntax exists to make them useful.
You need to dip into the compiler support for handling SEH exceptions. Use the __try, __except keywords (__finally is optional) and have your filter catch the exception code for a C++ exception, 0xe04d5343 ('MSC'). You do however lose the ability to catch a specific C++ exception type, that plumbing is buried in the CRT without source. Put a C++ try inside the __try to fix that so your __except only sees exceptions that the C++ code didn't filter.
Using SetUnhandledExceptionFilter() is another way to do this btw, you really should consider it to act as the ultimate backstop of any unhandled exception, independent of the code location. It is the best way to create a minidump of a crashing app. Last but not least, creating a minidump of a crashing app inside the process itself isn't the best approach. There are plenty of odds that this won't work well, the process state can be corrupted pretty badly. One failure mode is having the process heap locked. Not unlikely considering that heap damage is a very common crash reason. Fix that with a "guard process", use a named event to signal it to make a minidump. Your exception filter only needs to set the event, that always works.
Windows SEH and c++ exceptions are not intertwined in any way - the easy way to solve this is to use your own __try __except wrapping e.g. a dereference of a null pointer.
Something like:
__try {
* (int *) 0 = 0;
}
__except
(
eh_.WriteMinidumpForException(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER
)
{
}

How to catch the null pointer exception? [duplicate]

This question already has answers here:
Catching access violation exceptions?
(8 answers)
Closed 6 years ago.
try {
int* p = 0;
*p = 1;
} catch (...) {
cout << "null pointer." << endl;
}
I tried to catch the exception like this but it doesn't work,any help?
There's no such thing as "null pointer exception" in C++. The only exceptions you can catch, is the exceptions explicitly thrown by throw expressions (plus, as Pavel noted, some standard C++ exceptions thrown intrinsically by standard operator new, dynamic_cast etc). There are no other exceptions in C++. Dereferencing null pointers, division by zero etc. does not generate exceptions in C++, it produces undefined behavior. If you want exceptions thrown in cases like that it is your own responsibility to manually detect these conditions and do throw explicitly. That's how it works in C++.
Whatever else you seem to be looking for has noting to do with C++ language, but rather a feature of particular implementation. In Visual C++, for example, system/hardware exceptions can be "converted" into C++ exceptions, but there's a price attached to this non-standard functionality, which is not normally worth paying.
You cannot. De-referencing a null-pointer is a system thing.
On Linux, the OS raises signals in your application. Take a look at csignal to see how to handle signals. To "catch" one, you'd hook a function in that will be called in the case of SIGSEGV. Here you could try to print some information before you gracefully terminate the program.
Windows uses structured-exception-handling. You could use the instristics __try/__except, as outlined in the previous link. The way I did it in a certain debug utility I wrote was with the function _set_se_translator (because it closely matches hooks). In Visual Studio, make sure you have SEH enabled. With that function, you can hook in a function to call when the system raises an exception in your application; in your case it would call it with EXCEPTION_ACCESS_VIOLATION. You can then throw an exception and have it propagate back out as if an exception was thrown in the first place.
There is a very easy way to catch any kind of exception (division by zero, access violation, etc.) in Visual Studio using try -> catch (...) blocks.
A minor project tweaking is enough. Just enable the /EHa option in project settings. See Project Properties -> C/C++ -> Code Generation -> Modify the Enable C++ Exceptions to "Yes With SEH Exceptions". That's it!
See details here:
http://msdn.microsoft.com/en-us/library/1deeycx5(v=vs.80).aspx
Dereferencing a null (or pointer that's past-the-end of array, or a random invalid pointer) results in undefined behavior. There's no portable way to "catch" that.
C++ doesn't do pointer checking (although I suppose some implementations could). If you try to write to a null pointer it is most likely going to crash hard. It will not throw an exception. If you want to catch this you need to check the value of the pointer yourself before you try to write to it.
Generally you can't. Even if you could it would be like trying to put a band aid on a submarine that has sprung a leak.
A crippled application can do far more damage than one that has crashed. My advice here would be to let it crash then fix why it crashed. Rinse. Repeat.
As others have said, you can't do this in C++.
If I can make a broader point: even in a language that allows you to catch it, the better action is to not touch null pointers. Catching an error when it's already blown up in your face, then deciding to just move on like it didn't happen, is not a good coding strategy. Things like null pointer dereference, stack overflow, etc., should be seen as catastrophic events and defensively avoided, even if your language allows you to react to it differently.
There is no platform independent way to do this. Under Windows/MSVC++ you can use __try/__except
But I wouldn't recommend doing it anyway. You almost certainly cannot recover correctly from a segmentation fault.
If you wanted to you could just do the pointer checking yourself and throw...
if (p == nullptr) throw std::exception("woot! a nullptr!")
p->foo();
so course this would only be to debug the problem, the nullptr should not occur in the first place :)
Short answer- you can't in a portable or standard way, because bugs like this are potentially corrupting the process itself.
Long answer- you can do more than you might think, and definitely more than the default of the program just crashing. However, you need to keep 3 things in mind:
1) These bugs are MORE severe than exceptions and often cannot present as exceptions to your logic.
2) Your detection and library handling of them WILL be platform-dependent on the back end, even though you can provide a clean abstract interface for public consumption.
3) There will always be some crashes that are so bad you cannot even detect them before the end.
Basically, faults like segfaults or heap corruption are not exceptions because they're corrupting the actual process running the program. Anything you coded into the program is part of the program, including exception handling, so anything beyond logging a nice error message before the process dies is inadvisable in the few cases it isn't impossible. In POSIX, the OS uses a signaling system to report faults like these, and you can register callback functions to log what the error was before you exit. In Windows, the OS can sometimes convert them into normal-looking exceptions which you can catch and recover from.
Ultimately, however, your best bet is to code defensively against such nightmares. On any given OS there will be some that are so bad that you cannot detect them, even in principle, before your process dies. For example, corrupting your own stack pointer is something that can crash you so badly that even your POSIX signal callbacks never see it.
In VC++ 2013 (and also earlier versions) you can put breakpoints on exceptions:
Press Ctrl + Alt + Delete (this will open the exception dialog).
Expand 'Win32 Exceptions'
Ensure that "0xC0000005 Access Violation" exception is checked.
Now debug again, a breakpoint will be hit exactly when the the null dereference happened.
There is no NULL pointer exception exist in c++ but still you want to catch the same then you need to provide your own class implementation for the same.
below is the example for the same.
class Exception {
public:
Exception(const string& msg,int val) : msg_(msg),e(val) {}
~Exception( ) {}
string getMessage( ) const {return(msg_);}
int what(){ return e;}
private:
string msg_;
int e;
};
Now based on NULL pointer check it can be threw like , throw(Exception("NullPointerException",NULL));
and below is the code for catching the same.
catch(Exception& e) {
cout << "Not a valid object: " << e.getMessage( )<< ": ";
cout<<"value="<<e.what()<< endl;
}

Unlocking the critical section in case of non-C++ exceptions

I have a object of CCriticalSection in my class to synchronize the exceptions to a method. I use it with CSingleLock object like this:
void f()
{
try
{
CSingleLock lock(&m_synchronizer, TRUE);
.....
.....
}
catch(SomeException )
{
}
catch(...)
{
}
}
The critical section object is properly unlocked if any of the statement throws a C++ exception, however if I get any other type of exception (something like a access violation) is there any way I can unlock my critical section? I don't think RAII will help here as the stack unwinding doesn't happen. Is there any thing I can do to prevent the critical section being in locked state after exiting the function f?
EDIT Update
The destructor of CSingleLock will indeed unlock the underlying critical section. Access violations and the like are called SEH exceptions. As to whether or not the destructor will run in the face of an SEH exception is very environment specific. There are tricks you can do to make this type of scenario work.
For instance, one option is to translate all SEH exceptions into a corresponding C++ exception. I blogged recently on the technique to accomplish this. Once they're all C++ exceptions then the destructor being called is guaranteed.
http://blogs.msdn.com/jaredpar/archive/2008/01/11/mixing-seh-and-c-exceptions.aspx
But another question is why bother doing this? Once you're faced with at access violation the only thing your program can reliably do is crash.
Assuming you're using MSVC try compiling with the /EHa command line option which maps Windows' structured exceptions to C++ exceptions (the C++ docs sometimes call them 'asynchronous' exceptions).
You should read up on the implications of this - I don't use the option myself, and I'm not sure what the drawbacks might be.
You could also try using the __try, __except, __finally keywords to handle SEH yourself.
RAII does help here. The most important thing to not here is "going out of scope" is not necessarily just stack unwinding. When the try block is exited, either normally or through an exception, the destructor will be called. Anytime your variable goes out of scope its destructor is invoked.
Edit
Hmm it appears the question has been edited to focus on SEH (non C++ exceptions). In this case the destructor code might not be fired. However, as others have pointed out, most of the non-C++ exceptions are equivalent to application crashes. It may not be reasonable to react to these exceptions in any sane way other than to crash. In this case your app is exited and your critical section will be destroyed anyway.
See #JaredPar's answer for a good solution for translating C SEH exceptions to C++ exceptions for Windows.
If you really need your application to survive when a particular area of code performs an access violation, you should consider having that code in a separate process.
If code is trying to read or write to places it's not allowed, what's to stop it writing into other parts of your application's memory, causing all sorts of nasty problems?
AFAIK, you NEVER should use CCriticalSection nor any MFC synchronization object.