2008-08-12 27 views
6

J'ai une application MFC compilée avec/clr et j'essaie d'implémenter un gestionnaire final pour les exceptions managées autrement non interceptées. Pour les exceptions natives, la priorité CWinApp::ProcessWndProcException fonctionne.Dernier gestionnaire d'exceptions géré dans un exécutable mixte natif/géré?

Les deux événements suggérés dans Jeff CodeProject article, Application.ThreadException et AppDomain.CurrentDomain.UnhandledException ne sont pas déclenchés.

Quelqu'un peut-il suggérer un moyen de fournir un gestionnaire d'exceptions managé final pour un exécutable mixte?


Mise à jour:

Il semble que ces gestionnaires d'exceptions ne sont déclenchées en aval de Application.Run ou similaire (. Il y a une saveur de thread de travail, ne peut pas se rappeler le nom) Si vous voulez attraper vraiment à l'échelle mondiale un exception gérée, vous devez installer un filtre SEH. Vous n'allez pas obtenir un System.Exception et si vous voulez une callstack, vous devrez rouler votre propre walker.

Dans une question de forum MSDN sur ce sujet, il a été suggéré de remplacer un point suffisamment faible du thread principal MFC dans un try ... catch (Exception^). Par exemple, CWinApp::Run. C'est peut-être une bonne solution, mais je n'ai pas examiné les effets de perf ou de stabilité. Vous aurez une chance de vous connecter avec une pile d'appels avant de vous libérer et vous pourrez éviter le comportement d'exception non effacé des fenêtres par défaut.

+0

Peut-être que cela nous aiderait à en savoir plus sur les exceptions qui sont lancées et qui ne sont pas détectées par les deux événements que vous avez mentionnés? – Charlie

+0

Toute exception gérée - tout héritier de System :: Exception. Le point des événements ci-dessus est de se déclencher lorsque/any/l'exception gérée est non interceptée. –

Répondre

2

Jeter un oeil autour des internets, vous constaterez que vous devez installer un filtre pour obtenir les exceptions non gérées passer les filtres sur le chemin de votre AppDomain. De CLR and Unhandled Exception Filters:

Le CLR s'appuie sur le mécanisme de filtre d'exception non géré SEH pour intercepter les exceptions non gérées.

0

L'utilisation de ces deux gestionnaires d'exceptions devrait fonctionner. Etes-vous sûr que vous les avez ajouté dans un endroit où ils vont être appelés et réglé correctement (c.-à-dans de votre application gérée point d'entrée - vous avez mis un dans, non?)

+0

Je pense que le problème est qu'il n'y a pas Application.Run n'importe où. –

1

L'utilisation de ces deux gestionnaires d'exceptions devrait fonctionner.

Pourquoi "devrait?"

Les événements ne sont pas élevés en utilisant le ci-dessous:

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; 
}