混合本机/托管可执行文件中的最终托管异常处理程序?
-
08-06-2019 - |
题
我有一个使用 /clr 编译的 MFC 应用程序,并且我正在尝试为未捕获的托管异常实现最终处理程序。对于本机异常,重写 CWinApp::ProcessWndProcException
作品。
杰夫的书中提到的两个事件 代码项目文章,Application.ThreadException
和 AppDomain.CurrentDomain.UnhandledException
, ,没有提出。
任何人都可以建议一种为混合可执行文件提供最终托管异常处理程序的方法吗?
更新:
看来这些异常处理程序仅在下游触发 Application.Run
或类似的(有一个工作线程风格,不记得名字了。)如果你想真正全局捕获托管异常,你确实需要安装 SEH 过滤器。你不会得到一个 System.Exception
如果你想要一个调用堆栈,你将不得不滚动你自己的步行器。
在关于此主题的 MSDN 论坛问题中,建议覆盖主 MFC 线程的足够低级别的点 try ... catch (Exception^)
. 。例如, CWinApp::Run
. 。这可能是一个很好的解决方案,但我还没有考虑任何性能或稳定性影响。在退出之前,您将有机会使用调用堆栈进行日志记录,并且可以避免默认的 Windows 未处理的异常行为。
解决方案
浏览一下互联网,您会发现您需要安装一个过滤器,以使非托管异常通过过滤器到达您的 AppDomain。从 CLR 和未处理的异常过滤器:
CLR依赖SEH未处理异常过滤机制来捕获未处理异常。
其他提示
使用这两个异常处理程序应该可以工作。
为什么要?”
使用以下内容不会引发事件:
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;
}
使用这两个异常处理程序应该可以工作。您确定已将它们添加到将被调用并正确设置的位置(即在您的应用程序的 管理 入口点——你确实放了一个,对吧?)