问题
I have an MFC application compiled with /clr and I'm trying to implement a final handler for otherwise un-caught managed exceptions. For native exceptions, overriding CWinApp::ProcessWndProcException
works.
The two events suggested in Jeff's CodeProject article,Application.ThreadException
and AppDomain.CurrentDomain.UnhandledException
, are not raised.
Can anyone suggest a way to provide a final managed exception handler for a mixed executable?
Update:
It appears that these exception handlers are only triggered downstream of Application.Run
or similar (there's a worker thread flavor, can't remember the name.) If you want to truly globally catch a managed exception you do need to install an SEH filter. You're not going to get a System.Exception
and if you want a callstack you're going to have to roll your own walker.
In an MSDN forum question on this topic it was suggested to override a sufficiently low-level point of the main MFC thread in a try ... catch (Exception^)
. For instance, CWinApp::Run
. This may be a good solution but I haven't looked at any perf or stability implications. You'll get a chance to log with a call stack before you bail and you can avoid the default windows unahndled exception behavior.
回答1:
Taking a look around the internets, you'll find that you need to install a filter to get the unmanaged exceptions passing the filters on their way to your AppDomain. From CLR and Unhandled Exception Filters:
The CLR relies on the SEH unhandled exception filter mechanism to catch unhandled exceptions.
回答2:
Using those two exception handlers should work.
Why "should?"
The events are not raised using the below:
extern "C" void wWinMainCRTStartup();
// managed entry point
[System::STAThread]
int managedEntry( void )
{
FinalExceptionHandler^ handler = gcnew FinalExceptionHandler();
Application::ThreadException += gcnew System::Threading::ThreadExceptionEventHandler(
handler,
&FinalExceptionHandler::OnThreadException);
AppDomain::CurrentDomain->UnhandledException += gcnew UnhandledExceptionEventHandler(
handler,
&FinalExceptionHandler::OnAppDomainException);
wWinMainCRTStartup();
return 0;
}
// final thread exception handler implementation
void FinalExceptionHandler::OnThreadException( Object^ /* sender */, System::Threading::ThreadExceptionEventArgs^ t )
{
LogWrapper::log->Error( "Unhandled managed thread exception.", t->Exception );
}
// final appdomain exception handler implementation
void FinalExceptionHandler::OnAppDomainException(System::Object ^, UnhandledExceptionEventArgs ^args)
{
LogWrapper::log->Error( "Unhandled managed appdomain exception.", (Exception^)(args->ExceptionObject) );
}
BOOL CMyApp::InitInstance()
{
throw gcnew Exception("test unhandled");
return TRUE;
}
回答3:
Using those two exception handlers should work. Are you sure you've added them in a place where they're going to be called and properly set (ie, in your application's managed entry point -- you did put one in, right?)
来源:https://stackoverflow.com/questions/8704/final-managed-exception-handler-in-a-mixed-native-managed-executable