Конечный обработчик управляемых исключений в смешанном собственном / управляемом исполняемом файле - PullRequest
6 голосов
/ 12 августа 2008

У меня есть приложение MFC, скомпилированное с / clr, и я пытаюсь реализовать конечный обработчик для других неотслеживаемых управляемых исключений. Для собственных исключений работает переопределение CWinApp::ProcessWndProcException.

Два события, предложенные в статье CodeProject Джеффа , Application.ThreadException и AppDomain.CurrentDomain.UnhandledException, не возникают.

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


Обновление:

Похоже, что эти обработчики исключений срабатывают только после Application.Run или аналогичного (есть разновидность рабочего потока, имя не запоминается.) Если вы хотите по-настоящему глобально перехватить управляемое исключение, вам нужно установить SEH фильтр. Вы не получите System.Exception, и если вам нужен стек вызовов, вам придется катить своего собственного ходунка.

В вопросе на форуме MSDN по этой теме было предложено переопределить достаточно низкоуровневую точку основного потока MFC в try ... catch (Exception^). Например, CWinApp::Run. Это может быть хорошим решением, но я не смотрел на какие-либо последствия для стабильности или стабильности. У вас будет возможность войти в стек вызовов до того, как вы внесете залог, и вы сможете избежать поведения неустановленных исключений в окнах по умолчанию.

Ответы [ 3 ]

2 голосов
/ 10 октября 2008

Посмотрев по интернетам, вы обнаружите, что вам нужно установить фильтр, чтобы неуправляемые исключения передавали фильтры по пути к вашему AppDomain. От CLR и необработанных фильтров исключений :

CLR использует механизм фильтрации необработанных исключений SEH для захвата необработанных исключений.

1 голос
/ 18 августа 2008

Использование этих двух обработчиков исключений должно работать.

Почему "должен?"

События не генерируются с использованием следующего:

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;
}
0 голосов
/ 13 августа 2008

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

...