Конечный обработчик управляемых исключений в смешанном собственном / управляемом исполняемом файле?
У меня есть приложение MFC, скомпилированное с / clr, и я пытаюсь реализовать конечный обработчик для не обнаруженных в противном случае управляемых исключений. Для нативных исключений, переопределение CWinApp::ProcessWndProcException
работает.
Два события, предложенные в статье Джеффа CodeProject, Application.ThreadException
а также AppDomain.CurrentDomain.UnhandledException
не подняты.
Кто-нибудь может предложить способ предоставления окончательного управляемого обработчика исключений для смешанного исполняемого файла?
Обновить:
Похоже, что эти обработчики исключений срабатывают только после Application.Run
или подобное (есть разновидность рабочего потока, не могу вспомнить имя.) Если вы хотите по-настоящему глобально перехватить управляемое исключение, вам нужно установить фильтр SEH. Вы не собираетесь получить System.Exception
и если вы хотите стека вызовов, вам придется катить свой собственный ходок.
В вопросе форума MSDN по этой теме было предложено переопределить достаточно низкоуровневую точку основного потока MFC в try ... catch (Exception^)
, Например, CWinApp::Run
, Это может быть хорошим решением, но я не смотрел на какие-либо последствия для стабильности или стабильности. У вас будет возможность войти в стек вызовов перед тем, как вы получите залог, и вы сможете избежать стандартного поведения неустановленных исключений в Windows.
3 ответа
Посмотрев по интернетам, вы обнаружите, что вам нужно установить фильтр, чтобы неуправляемые исключения передавали фильтры по пути к вашему 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;
}
Использование этих двух обработчиков исключений должно работать. Вы уверены, что добавили их в место, где они будут вызываться и правильно настраиваться (т. Е. В управляемой точке входа вашего приложения - вы ее ввели, верно?)