Конечный обработчик управляемых исключений в смешанном собственном / управляемом исполняемом файле?

У меня есть приложение 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;
}

Использование этих двух обработчиков исключений должно работать. Вы уверены, что добавили их в место, где они будут вызываться и правильно настраиваться (т. Е. В управляемой точке входа вашего приложения - вы ее ввели, верно?)

Другие вопросы по тегам