混合本机/托管可执行文件中的最终托管异常处理程序?
时间: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.