混合本机/托管可执行文件中的最终托管异常处理程序?

时间:2020-03-05 18:39:09  来源:igfitidea点击:

我有一个用/ clr编译的MFC应用程序,我正在尝试为未捕获的托管异常实现最终处理程序。对于本地异常,可以重写CWinApp :: ProcessWndProcException。

Jeff的CodeProject文章中建议的两个事件分别是Application.ThreadException和AppDomain.CurrentDomain.UnhandledException。

谁能建议一种为混合可执行文件提供最终托管异常处理程序的方法?

更新:

看来这些异常处理程序仅在Application.Run或者类似的下游触发(有工作线程的味道,不记得名称了。)如果要真正全局地捕获托管异常,则需要安装SEH筛选。我们不会得到System.Exception,并且如果我们想要一个调用栈,则必须使用自己的助行器。

在有关此主题的MSDN论坛问题中,建议在" try ... catch(Exception ^)"中覆盖MFC主线程的足够低级别的点。例如,CWinApp :: Run。这可能是一个很好的解决方案,但是我没有考虑任何性能或者稳定性方面的问题。在保释之前,我们将有机会使用调用堆栈进行日志记录,并且可以避免默认的Windows不受约束的异常行为。

解决方案

回答

使用这两个异常处理程序应该可以工作。我们确定已将它们添加到将被调用并正确设置的位置(即,在应用程序的托管入口点中,我们确实将其中一个放进去了吗?)

回答

Using those two exception handlers should work.

为什么要?"

使用以下方法不引发事件:

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;
}

回答

环顾互联网,我们会发现需要安装一个过滤器,以使非托管异常将过滤器传递到AppDomain。从CLR和未处理的异常过滤器:

The CLR relies on the SEH unhandled exception filter mechanism to catch unhandled exceptions.