1

C# および C++ コードで構成される .NET アプリケーション (サービス) があります。

C++ コードの「クラッシュ」(つまりSystem.AccessViolationException、その他の破損状態の例外) は (「非」) 正しく処理され、(ログに記録される) 私のハンドラーに直接導かれAppDomain.CurrentDomain.UnhandledException、​​アプリケーションが終了し、WER ダンプ ファイルが次の場合に書き込まれます。そのように構成されています(それはそうです)。

このアプリケーションでは、これSystem.NullReferenceExceptionは常にバグであると判断しました。特に、一部の C++/CLI アクセス違反のバグでは、AV ではなくこのバグが報告されるためです。

.NETが例外境界 (この場合は私のコールバック) で をキャッチしないようにする方法はありますか?代わりに、スタックを巻き戻さにアプリを直接終了し、基本的に に直接「ジャンプ」しますか?NullReferenceExceptionOnTimerAppDomain.CurrentDomain.UnhandledException

4

2 に答える 2

2

あなたは出来る:

AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;

その後

static void CurrentDomain_FirstChanceException(object sender, FirstChanceExceptionEventArgs e)
{
    if (e.Exception is NullReferenceException)
    {
        Environment.FailFast("FailFast", e.Exception);
    }
}

Environment.FailFast:_

Windows アプリケーション イベント ログにメッセージを書き込んだ後、すぐにプロセスを終了し、Microsoft へのエラー レポートにそのメッセージを含めます。

このメソッドは、アクティブな try/finally ブロックまたはファイナライザーを実行せずにプロセスを終了します。

明らかに、CurrentDomain_FirstChanceExceptionおそらくあなたが持っているロギングコードを複製することができますUnhandledException(または両方によって呼び出される共通のメソッドがあります)

于 2016-02-19T11:14:28.773 に答える
1

実際には「単純な」グローバル例外フィルターであるという事実によりFirstChanceException、私は軌道に乗りました(それが「正しい」軌道であるかどうかはまだわかりません):

CLI にはすでに例外フィルターがあります

C# 6 で作業する余裕がある場合は、次のように簡単です。

        try
        {
            throw new NullReferenceException("No, Really");
        }
        catch(Exception ex) when (FilterExType(ex))
        {
            Console.WriteLine($"2: Caught 'any' exception: {ex}");
        }

    static bool FilterExType(Exception ex)
    {
        if (ex is NullReferenceException)
        {
            Environment.FailFast("BOOM from C#!", ex);
        }
        // always handle if we return
        return true;
    }

そして、以前のバージョンに固執している私たち (私のような) の場合、デリゲート/ラムダを介して VB.NET を介してフィルタリングをルーティングできます。

        try {
            VbFilterLib.FilteredRunner.RunFiltered(() =>
            {
                throw new NullReferenceException("Via VB.NET");
            });
        } 
        catch (Exception ex)
        {
            Console.WriteLine("1: Caught 'any' exception: {0}", ex");
        }

VBをそのまま使用します(ご容赦ください。VB.NETは私が堪能な言語とはほど遠いです):

Public Class FilteredRunner
    Delegate Sub VoidCode()

    Private Shared Function FilterAction(x As Exception) As Boolean
        If TypeOf x Is NullReferenceException Then
            Environment.FailFast("Abort program! Investigate Bug via crash dump!", x)
        End If
        ' Never handle here:'
        Return False
    End Function

    Public Shared Sub RunFiltered(code As VoidCode)
        Try
            code.Invoke()
        Catch ex As Exception When FilterAction(ex)
            Throw New InvalidProgramException("Unreachable!", ex)
        End Try
    End Sub

End Class

明らかに、それを機能させるには、さらに構成のリギングが必要ですが、それはまさに私が望んでいることのようです. :-)

于 2016-02-19T20:16:24.670 に答える