Is it possible for the consumer of the library to override C ++ exception handling?
I have a C ++ DLL with code like this:
LogMessage( "Hello world" );
try {
throw new int;
} catch( int* e ) {
LogMessage( "Caught exception" );
delete e;
}
LogMessage( "Done" );
This DLL is loaded by some third party application and the code above is called. The problem is that only the first LogMessage
is called - although there is an exception handler, the control flow is passed to the unknown.
I see this and can't decide if there is some obscure bug to investigate or just the evil force of a consumer application.
Can a consumer application actually override C ++ exception handling in a DLL?
EDIT: Problem solved after thinking about all the things to check the outlined in the answers. In real code, it doesn't just throw, there is a special function to throw exceptions, which has a call to MessageBoxW () Win32 in the debug version. And the consumer application had problems showing the message box (this is an NT service) and effectively hung up. So this is not a C ++ exception handling problem anyway.
a source to share
The code looks good to me, but I'd be tempted to add some more catch clauses to see if it hits one of the others. Namely, I would add:
catch (const std :: exception & ex) {
... log exception ...
}
catch (...) {
... log exception ..
}
I would expect it to either hit the pointer trick (even if it really isn't a good idea, see the link that Igor Oks provided) or std :: exception if it can't allocate memory. However, it must hit one of the three catch clauses to rule out the possibility of an exception from the DLL.
I would also change the object that was added to the value type (even if it was int) and update the catch clause accordingly to see if you changed that way.
a source to share
The code is fine. I accomplished it with this function:
void LogMessage( char* s )
{
cout << s << endl;
}
And got the correct output:
Hello World
Exception fixed
Done
Is it possible that there is some problem with your LogMessage function?
I would suggest investigating (with a debugger or adding debug footprints) if your threads end up in the try block and if it reaches the catch block.
Not a problem, it is still unclear what you are achieving by casting a pointer, not a value. I would recommend not using catch-by-pointer, see the argument here in C ++ - Frequently Asked Question.
a source to share
The code looks fine. But can you check if there is any unhandled exception before the structured exception is thrown throw new int;
.
LogMessage( "Hello world" );
try {
//some unhandled exception here
throw new int;
} catch( int* e ) {
LogMessage( "Caught exception" );
delete e;
}
LogMessage( "Done" );
If so, you can check for the same using SetUnhandledExceptionFilter .
If the DLL already provides an unhandled exception filter, and if it returns EXCEPTION_EXECUTE_HANDLER
, then your exception handler will not be called.
You need to use _set_se_translator
to convert win32 exceptions to C ++ structured exceptions.
a source to share