7

/clr でコンパイルされた MFC アプリケーションがあり、キャッチされないマネージ例外の最終ハンドラーを実装しようとしています。ネイティブ例外の場合、オーバーライドCWinApp::ProcessWndProcExceptionが機能します。

Jeff のCodeProject 記事で提案されている 2 つのイベントApplication.ThreadExceptionAppDomain.CurrentDomain.UnhandledExceptionは発生しません。

混合実行可能ファイルに最終的なマネージド例外ハンドラーを提供する方法を提案できる人はいますか?


アップデート:

これらの例外ハンドラーは、ダウンストリームApplication.Runまたは同様のものでのみトリガーされるようです (ワーカー スレッド フレーバーがあり、名前を思い出せません)。マネージ例外を完全にグローバルにキャッチしたい場合は、SEH フィルターをインストールする必要があります。System.Exceptionコールスタックが必要な場合は、独自のウォーカーをロールバックする必要があります。

このトピックに関する MSDN フォーラムの質問では、try ... catch (Exception^). たとえば、CWinApp::Run. これは良い解決策かもしれませんが、パフォーマンスや安定性への影響については調べていません。保釈する前にコール スタックをログに記録する機会が得られ、デフォルトの Windows 未処理の例外動作を回避できます。

4

3 に答える 3

2

インターネットを見回すと、フィルターをインストールして、AppDomain に向かう途中でフィルターを通過するアンマネージ例外を取得する必要があることがわかります。CLR および未処理の例外フィルターから:

CLR は、未処理の例外をキャッチするために、SEH 未処理の例外フィルター メカニズムに依存しています。

于 2008-10-10T19:25:41.983 に答える
1

これら 2 つの例外ハンドラーを使用すると機能するはずです。

どうして〜しなきゃいけない?"

イベントは、以下を使用して発生しません。

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;
}
于 2008-08-18T19:55:42.193 に答える
0

これら 2 つの例外ハンドラーを使用すると機能するはずです。それらが呼び出されて適切に設定される場所にそれらを追加したことは確かですか (つまり、アプリケーションのマネージエントリ ポイントに追加しましたか?)

于 2008-08-13T03:10:36.670 に答える