Final managed exception-handler in eine gemischte native/managed executable?
-
08-06-2019 - |
Frage
Ich habe eine MFC-Anwendung kompiliert mit /clr und ich bin versucht zu implementieren, die eine endgültige handler für die sonst un-gefangen verwaltete Ausnahmen.Für native Ausnahmen, überschreiben CWinApp::ProcessWndProcException
funktioniert.
Die beiden Ereignisse vorgeschlagen, Jeff CodeProject-Artikel,Application.ThreadException
und AppDomain.CurrentDomain.UnhandledException
, werden nicht erhoben.
Kann jemand einen Weg vorschlagen, um eine endgültige managed exception-handler für eine gemischte ausführbare?
Update:
Es scheint, dass diese Ausnahme-Handler sind nur ausgelöst, hinter Application.Run
oder ähnlich (es ist ein worker-thread Geschmack hat, kann nicht an den Namen erinnern.) Wenn Sie wollen, um wirklich Global zu fangen verwaltet Ausnahme, die Sie tun müssen, um installieren Sie eine SEH-filter.Du wirst es nicht bekommen System.Exception
und wenn Sie wollen eine Aufrufliste, die Sie gehen zu müssen, Rollen Sie Ihre eigene walker.
In einem MSDN-forum Frage zu diesem Thema, es wurde vorgeschlagen, überschreiben Sie ausreichend Tiefpunkt der wichtigsten MFC-Faden in einer try ... catch (Exception^)
.Für Beispiel, CWinApp::Run
.Dies kann eine gute Lösung sein, aber ich habe nicht geschaut in jedem perf oder der Stabilität Folgen.Sie werden die chance bekommen, melden Sie sich mit einem call-stack bevor Sie die Kaution und Sie können verhindern, dass die Standard-windows-unahndled Ausnahme Verhalten.
Lösung
Ein Blick rund um das Internet, werden Sie feststellen, dass Sie brauchen, um installieren Sie einen filter, um die nicht verwalteten Ausnahmen bestehen der Filter auf Ihrem Weg zu Ihrer Anwendungsdomäne.Von CLR und nicht Behandelte Ausnahme Filter:
CLR setzt auf die SEH-nicht behandelte Ausnahme filter-Mechanismus zu fangen unbehandelte Ausnahmen.
Andere Tipps
Mit diesen beiden Ausnahme-Handler funktionieren sollte.
Warum "sollte?"
Die Ereignisse werden nicht ausgelöst, mit der unter:
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;
}
Mit diesen beiden Ausnahme-Handler funktionieren sollte.Sind Sie sicher, dass Sie Hinzugefügt haben, können Sie Sie in einem Ort, wo Sie gehen, genannt zu werden und richtig eingestellt (dh in Ihrer Anwendung managed entry point-du hast in, right?)