views:

139

answers:

5

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 invoked. The problem is only the first LogMessage is invoked - even though there's an exception handler the control flow is transferred to the unknown.

I see this and can't decide whether it's some obscure bug to be investigated or just the evil force of the consumer application.

Is it really possible for a consumer application to override the C++ exception handling in a DLL?

EDIT: The problem resolved after thinking on all things to check outlined in the answers. In real code it's not just throw, there'a a special function for throwing exceptions that has a call to MessageBoxW() Win32 call in debug version. And the consumer application had troubles showing the message box (it's an NT service) and effectively hung up. So it's not a problem of C++ exceptions handling in any way.

+1  A: 

The code is OK. I executed it with this function:

void LogMessage( char* s )
{
  cout << s << endl;
}

And got the correct output:

Hello world

Caught exception

Done

Is it possible that there is some problem with your LogMessage function?

I would suggest to investigate (by debugger or adding debug prints), whether your flows reaches the try block, and whether it reaches the catch block.

Not being a problem, it still isn't clear, what do you achieve by throwing a pointer and not a value. I would recommend not to use catch-by-pointer, see the reasoning here, at the C++-FAQ-lite.

Igor Oks
Highly unlikely. It works allright the first time and looks like nothing could prevent it from working allright later.
sharptooth
+1  A: 
Timo Geusch
I accept this answer because it offers the broadest list of things to check while debugging such issues.
sharptooth
+1  A: 

First, please check whether the LogMessage call flushes the output (use << endl).

Although far-fetched, is it possible that the new call is throwing an exception (out of memory)? I'd consider that as one reason not to new exceptions (just to add to what Igor said).

Amit Kumar
+1  A: 

The code looks okay. But can you check if there any unhandled exception before the structured exception throw new int; is thrown.

LogMessage( "Hello world" );
try {

     //some unhandled exception here 

    throw new int;
} catch( int* e ) {
    LogMessage( "Caught exception" );
    delete e;
}
LogMessage( "Done" );

If that is the case then you can check the same using SetUnhandledExceptionFilter function.

If the DLL already provides an unhandled exception filter and if that returns EXCEPTION_EXECUTE_HANDLER then your exception handler will not be called.

You need to use _set_se_translator to convert the win32 exceptions to c++ structured exceptions.

aJ
A: 

The giveaway is actually in the EDIT. "MessageBoxW() ... NT service ... effectively hung up.". That's a fair description. The message box is on a desktop not associated with a logged-in user. Hence, it's still there, waiting for a mouseclick that will never happen.

MSalters