Final managed exception handler in a mixed native/managed executable?

爱⌒轻易说出口 提交于 2020-01-14 08:41:28

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!