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

时间:2008-08-12 11:48:53

标签: exception executable mixed unhandled

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

杰夫的CodeProject articleApplication.ThreadExceptionAppDomain.CurrentDomain.UnhandledException中提出的两个事件未被提出。

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


更新

看来这些异常处理程序只在Application.Run或类似的下游触发(有一个工作线程的味道,不能记住名称。)如果你想真正全局捕获托管异常,你需要安装SEH过滤器。你不会得到一个System.Exception,如果你想要一个callstack,你将不得不推出自己的助行器。

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

3 个答案:

答案 0 :(得分:2)

浏览一下互联网,您会发现需要安装一个过滤器来获取非托管异常,这些异常会在过滤到AppDomain的过程中通过过滤器。来自CLR and Unhandled Exception Filters

  

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

答案 1 :(得分: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;
}

答案 2 :(得分:0)

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