ネイティブ/マネージド実行可能ファイルが混在した最終マネージド例外ハンドラー?

StackOverflow https://stackoverflow.com/questions/8704

質問

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

Jeff の記事で提案された 2 つのイベント コードプロジェクトの記事,Application.ThreadException そして AppDomain.CurrentDomain.UnhandledException, 、上げられません。

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


アップデート:

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

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

役に立ちましたか?

解決

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

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

他のヒント

これら 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;
}

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top