7

我有一个用 /clr 编译的 MFC 应用程序,我正在尝试为其他未捕获的托管异常实现最终处理程序。对于本机异常,覆盖CWinApp::ProcessWndProcException有效。

Jeff 的CodeProject 文章中建议的两个事件,Application.ThreadExceptionAppDomain.CurrentDomain.UnhandledException, 没有引发。

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


更新:

似乎这些异常处理程序仅在下游Application.Run或类似情况下触发(有工作线程风格,不记得名称。)如果您想真正全局捕获托管异常,则需要安装 SEH 过滤器。你不会得到一个System.Exception,如果你想要一个调用堆栈,你将不得不滚动你自己的助行器。

在有关此主题的 MSDN 论坛问题中,建议覆盖try ... catch (Exception^). 例如,CWinApp::Run. 这可能是一个很好的解决方案,但我没有研究过任何性能或稳定性影响。在保释之前,您将有机会使用调用堆栈进行日志记录,并且可以避免默认的 windows unahndled 异常行为。

4

3 回答 3

2

浏览一下 Internet,您会发现您需要安装一个过滤器,以使非托管异常在到达您的 AppDomain 的过程中通过过滤器。从CLR 和未处理的异常过滤器

CLR 依靠 SEH 未处理的异常过滤器机制来捕获未处理的异常。

于 2008-10-10T19:25:41.983 回答
1

使用这两个异常处理程序应该可以工作。

为何要?”

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

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;
}
于 2008-08-18T19:55:42.193 回答
0

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

于 2008-08-13T03:10:36.670 回答