51

私はC#用のANTLRパーサーライブラリを使用してプロジェクトに取り組んでいます。私はいくつかのテキストを解析するための文法を構築しました、そしてそれはうまくいきます。ただし、パーサーが不正または予期しないトークンに遭遇すると、多くの例外の1つをスローします。問題は、場合によっては(すべてではない)、try / catchブロックがそれをキャッチせず、代わりに未処理の例外として実行を停止することです。

私にとっての問題は、この問題を他の場所では再現できないことですが、完全なコードでしか再現できません。呼び出しスタックは、例外がtry / catch(Exception)ブロック内で確実に発生することを示しています。私が考えることができる唯一のことは、私のコードと例外をスローするコードの間にいくつかのANTLRアセンブリ呼び出しが発生し、このライブラリではデバッグが有効になっていないため、ステップスルーできないことです。デバッグ不可能なアセンブリが例外バブリングを禁止するのだろうか?呼び出しスタックは次のようになります。外部アセンブリ呼び出しはAntlr.Runtimeにあります:

    Expl.Itinerary.dll!TimeDefLexer.mTokens()行1213 C#
    Antlr3.Runtime.dll!Antlr.Runtime.Lexer.NextToken()+0xfcバイト
    Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.FillBuffer()+0x22cバイト   
    Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.LT(int k = 1)+0x68バイト
    Expl.Itinerary.dll!TimeDefParser.prog()行109 + 0x17バイトC#
    Expl.Itinerary.dll!Expl.Itinerary.TDLParser.Parse(string Text = ""、Expl.Itinerary.IItinerary Itinerary = {Expl.Itinerary.MemoryItinerary})行17 + 0xaバイトC#

Parse()の一番下の呼び出しからのコードスニペットは次のようになります。

     try {
        // Execution stopped at parser.prog()
        TimeDefParser.prog_return prog_ret = parser.prog();
        return prog_ret == null ? null : prog_ret.value;
     }
     catch (Exception ex) {
        throw new ParserException(ex.Message, ex);
     }

私にとって、catch(Exception)句は、あらゆる例外をキャプチャする必要がありました。そうしない理由はありますか?

更新: Reflectorを使用して外部アセンブリをトレースしましたが、スレッド化の形跡はまったく見つかりませんでした。アセンブリは、ANTLRで生成されたコードのランタイムユーティリティクラスのようです。スローされる例外はTimeDefLexer.mTokens()メソッドからのものであり、そのタイプはNoViableAltExceptionであり、RecognitionException->Exceptionから派生します。この例外は、レクサーがストリーム内の次のトークンを理解できない場合にスローされます。つまり、入力が無効です。この例外は発生することが想定されていますが、try/catchブロックによってキャッチされているはずです。

また、ParserExceptionの再スローは、この状況とはまったく関係ありません。これは、解析中に例外を受け取り、自分のParserExceptionに変換する抽象化レイヤーです。私が経験している例外処理の問題は、そのコード行に到達することはありません。実際、「新しいParserExceptionをスローする」部分をコメントアウトしても、同じ結果が得られました。

もう1つ、問題の元のtry / catchブロックを変更して、代わりにNoViableAltExceptionをキャッチし、継承の混乱を排除しました。私はまだ同じ結果を受け取りました。

ある人は、デバッグモードでVSが処理された例外をキャッチするのに過度にアクティブになることがあると提案しましたが、この問題はリリースモードでも発生します。

男、私はまだ困惑しています!以前は触れていませんでしたが、VS 2008を実行していて、コードはすべて3.5です。外部アセンブリは2.0です。また、私のコードのいくつかは、2.0アセンブリのクラスをサブクラス化します。バージョンの不一致がこの問題を引き起こす可能性がありますか?

更新2: .NET3.5コードの関連部分を.NET2.0プロジェクトに移植し、同じシナリオを複製することで、.NETバージョンの競合を解消することができました。.NET 2.0で一貫して実行しているときに、同じ未処理の例外を複製することができました。

ANTLRが最近3.1をリリースしたことを知りました。そこで、3.0.1からアップグレードして再試行しました。生成されたコードは少しリファクタリングされていることがわかりましたが、同じ未処理の例外が私のテストケースで発生します。

更新3:このシナリオを簡略化されたVS2008プロジェクト に複製しました。プロジェクトをダウンロードして、自分で調べてみてください。私はすべての素晴らしい提案を適用しましたが、この障害をまだ克服することができていません。

回避策を見つけることができる場合は、調査結果を共有してください。再度、感謝します!


ありがとうございますが、VS2008は未処理の例外で自動的に中断します。また、[デバッグ]->[例外]ダイアログがありません。スローされるNoViableAltExceptionは完全に意図されており、ユーザーコードによってキャッチされるように設計されています。期待どおりにキャッチされないため、未処理の例外としてプログラムの実行が予期せず停止します。

スローされる例外はExceptionから派生したものであり、ANTLRでマルチスレッドが実行されることはありません。

4

25 に答える 25

30

私は問題を理解していると信じています。例外はキャッチされています。問題は、デバッガーの動作に関する混乱と、再現しようとしている各ユーザー間のデバッガー設定の違いです。

あなたの再現からの3番目のケースでは、次のメッセージが表示されていると思います:「NoViableAltException was unhandled by user code」と、次のようなコールスタック:

         【外部コード】    
    > TestAntlr-3.1.exe!TimeDefLexer.mTokens() 行 852 + 0xe バイト C#
        【外部コード】
        TestAntlr-3.1.exe!TimeDefParser.prog() 141 行目 + 0x14 バイト C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.ParseTest(string Text = "foobar;") 49 行目 + 0x9 バイト C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.Main(string[] args = {string[0x00000000]}) 30 行目 + 0xb バイト C#
        【外部コード】

コールスタック ウィンドウを右クリックして turn on show external code を実行すると、次のように表示されます。

        Antlr3.Runtime.dll!Antlr.Runtime.DFA.NoViableAlt(int s = 0x00000000, Antlr.Runtime.IIntStream 入力 = {Antlr.Runtime.ANTLRStringStream}) + 0x80 バイト   
        Antlr3.Runtime.dll!Antlr.Runtime.DFA.Predict(Antlr.Runtime.IIntStream 入力 = {Antlr.Runtime.ANTLRStringStream}) + 0x21e バイト  
    > TestAntlr-3.1.exe!TimeDefLexer.mTokens() 行 852 + 0xe バイト C#
        Antlr3.Runtime.dll!Antlr.Runtime.Lexer.NextToken() + 0xc4 バイト
        Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.FillBuffer() + 0x147 バイト   
        Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.LT(int k = 0x00000001) + 0x2d バイト  
        TestAntlr-3.1.exe!TimeDefParser.prog() 141 行目 + 0x14 バイト C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.ParseTest(string Text = "foobar;") 49 行目 + 0x9 バイト C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.Main(string[] args = {string[0x00000000]}) 30 行目 + 0xb バイト C#
        [管理された移行にネイティブ]  
        【マネージドからネイティブへの移行】  
        mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x39 バイト    
        Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2b バイト  
        mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(オブジェクトの状態) + 0x3b バイト   
        mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext、System.Threading.ContextCallback コールバック、オブジェクト状態) + 0x81 バイト    
        mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x40 バイト

デバッガーのメッセージは、コードの外部 (NoViableAlt から) で発生した例外が、処理されずに TestAntlr-3.1.exe!TimeDefLexer.mTokens() で所有するコードを通過していることを示しています。

言葉遣いは紛らわしいですが、例外がキャッチされないという意味ではありません。デバッガーは、mTokens()" を所有するコードがスローされるこの例外に対して堅牢である必要があることを知らせています。

問題を再現しなかった人にこれがどのように見えるかを確認するために試してみること:

  • Tools/Options/Debugging に移動し、「Enable Just My code (Managed only)」をオフにします。またはオプション。
  • Debugger/Exceptions に移動し、Common-Language Runtime Exceptions の「User-unhandled」をオフにします。
于 2008-09-03T05:27:31.937 に答える
9

アセンブリがリリースビルドとしてコンパイルされているかどうかに関係なく、例外は確実に呼び出し元に「バブル」する必要があります。デバッグモードでコンパイルされていないアセンブリがそれに影響を与える理由はありません。

ダニエルがおそらく例外が別のスレッドで発生していることを示唆していることに同意します-Application.ThreadExceptionでスレッド例外イベントをフックしてみてください。これは、未処理のスレッド例外が発生したときに発生する必要があります。このようにコードを適応させることができます:-

using System.Threading;

...

void Application_ThreadException(object sender, ThreadExceptionEventArgs e) {
  throw new ParserException(e.Exception.Message, e.Exception);
}    

 ...

 var exceptionHandler = 
    new ThreadExceptionEventHandler(Application_ThreadException);
 Application.ThreadException += exceptionHandler;
 try {
    // Execution stopped at parser.prog()
    TimeDefParser.prog_return prog_ret = parser.prog();
    return prog_ret == null ? null : prog_ret.value;
 }
 catch (Exception ex) {
    throw new ParserException(ex.Message, ex);
 }
 finally {
    Application.ThreadException -= exceptionHandler;
 }
于 2008-08-30T15:34:44.723 に答える
8

ここで何が起こっているのか教えてあげましょう...

Visual Studioは、例外が処理されていないと見なしているため、壊れています。unhandledとはどういう意味ですか?さて、Visual Studioでは、ツール...オプション...デバッグ...一般...「自分のコードだけを有効にする(管理対象のみ)」に設定があります。これがチェックされ、例外がコードから、「NOT YOUR CODE」(たとえば、Antlr)であるアセンブリに存在するメソッド呼び出しに関連付けられたスタックフレームに伝播する場合、それは「未処理」と見なされます。このため、[コードだけを有効にする]機能をオフにします。しかし、あなたが私に尋ねるなら、これは不完全です...あなたがこれをするとしましょう:

ExternalClassNotMyCode c = new ExternalClassNotMyCode();
try {
    c.doSomething( () => { throw new Exception(); } );
}
catch ( Exception ex ) {}

doSomethingがそこで無名関数を呼び出し、その関数が例外をスローします...

「コードだけを有効にする」がオンになっている場合、これはVisualStudioによると「未処理の例外」であることに注意してください。また、デバッグモードではブレークポイントのように停止しますが、非デバッグ環境または本番環境では、コードは完全に有効であり、期待どおりに機能することに注意してください。また、デバッガーで「続行」するだけで、アプリは順調に進みます(スレッドは停止しません)。例外がコード内(つまり外部ライブラリ内)にないスタックフレームを介して伝播するため、「未処理」と見なされます。あなたが私に尋ねるなら、これはお粗末です。このデフォルトの動作をMicrosoftに変更してください。これは、例外を使用してプログラムロジックを制御する完全に有効なケースです。場合によっては、サードパーティのライブラリを他の方法で動作するように変更できないことがあります。

MyBatisを例にとると、この手法を使用して、SqlMapper.QueryWithRowDelegateの呼び出しによって収集されているレコードの処理を停止できます。

于 2012-01-20T19:33:28.680 に答える
5

.Net 1.0 または 1.1 を使用していますか? その場合、catch(Exception ex) はアンマネージ コードからの例外をキャッチしません。代わりに catch {} を使用する必要があります。詳細については、次の記事を参照してください。

http://www.netfxharmonics.com/2005/10/net-20-trycatch-and-trycatchexception/

于 2008-08-30T16:07:42.960 に答える
4

私は@Shaun Austinと一緒です-tryを完全修飾名でラップしてみてください

catch (System.Exception)

それが役立つかどうかを確認してください.ANTLRドキュメントには、どの例外をスローする必要があると書かれていますか?

于 2008-09-02T17:08:45.083 に答える
3

例外が別のスレッドでスローされている可能性はありますか?明らかに、呼び出し元のコードはシングルスレッドですが、使用しているライブラリが内部でマルチスレッド操作を実行している可能性があります。

于 2008-08-30T15:10:36.170 に答える
2

Steve Steinerは、例外がantlrライブラリで発生し、mTokens()メソッドを通過して、antlrライブラリでキャッチされていることを正しく示しています。問題は、このメソッドがantlrによって自動生成されることです。したがって、mTokens()で例外を処理するための変更は、パーサー/レクサークラスを生成するときに上書きされます。

デフォルトでは、antlrはエラーをログに記録し、解析の回復を試みます。これをオーバーライドして、エラーが発生したときにparser.prog()が例外をスローするようにすることができます。サンプルコードから、これはあなたが期待していた動作だと思います。

このコードをグラマー(.g)ファイルに追加します。また、デバッグメニューで[マイコードを有効にする]をオフにする必要があります。

@members {

    public override Object RecoverFromMismatchedSet(IIntStream input,RecognitionException e,    BitSet follow)  
    {
        throw e;
    }
}

@rulecatch {
    catch (RecognitionException e) 
    {
        throw e;
    }
}

これは、「DefinitiveANTLRReference」の本の「Exitingtherecogniser onfirsterror」の章に記載されている例のC#バージョンでの私の試みです。

これがあなたが探していたものであることを願っています。

于 2009-03-10T12:57:13.393 に答える
2

うーん、問題がわかりません。サンプルソリューションファイルをダウンロードして試してみました。

TimeDefLexer.csの852行目で例外がスローされ、その後、Handledexceptionとだけ表示されるProgram.csのcatchブロックによって処理されます

その上のcatchブロックのコメントを解除すると、代わりにそのブロックに入ります。

ここで何が問題になっているようですか?

Kibbeeが言ったように、Visual Studioは例外で停止しますが、続行するように要求すると、例外はコードによってキャッチされます。

于 2008-09-02T20:47:39.783 に答える
2

サンプルのVS2008プロジェクトをダウンロードしましたが、ここでも少し困惑しています。私は例外を乗り越えることができましたが、おそらくうまくいく方法ではないでしょうが、あなたにとっては素晴らしいことです。しかし、これが私が見つけたものです:

このメーリングリストの投稿には、あなたが経験しているのと同じ問題のように見えるものについての議論がありました。

そこから、メインのprogram.csファイルにいくつかのダミークラスを追加しました。

class MyNoViableAltException : Exception
{
    public MyNoViableAltException()
    {
    }
    public MyNoViableAltException(string grammarDecisionDescription, int decisionNumber, int stateNumber, Antlr.Runtime.IIntStream input)
    {
    }
}
class MyEarlyExitException : Exception
{
    public MyEarlyExitException()
    {
    }

    public MyEarlyExitException(int decisionNumber, Antlr.Runtime.IIntStream input)
    {
    }
}

次に、使用行をTimeDefParser.csとTimeDefLexer.csに追加しました。

using NoViableAltException = MyNoViableAltException;
using EarlyExitException = NoViableAltException; 

これにより、例外は偽の例外クラスにバブルされ、そこで処理できますが、TimeDefLexer.csのmTokensメソッドで例外がスローされていました。そのクラスのtrycatchでそれをラップすると、例外がキャッチされました。

            try
            {
                alt4 = dfa4.Predict(input);
            }
            catch
            {
            }

スレッドが機能していない場合にエラーを処理するために呼び出される場所ではなく、内部メソッドでラップする理由は本当にわかりませんが、とにかく、それが私より賢い人を正しい方向に向けることを願っています。

于 2008-09-02T22:27:54.363 に答える
2

個人的には、スレッド化理論にはまったく納得していません。

以前にこれを見たことがありますが、例外も定義されているライブラリを使用していて、実際の Catch が別の「例外」タイプを参照していたことを意味していました (完全に修飾されていた場合、それは Company. Lib.Exception しかし、それは使用のためではありませんでした) スローされた通常の例外 (私が正しく覚えていれば、ある種の引数例外) をキャッチすることになると、型が一致しなかったためにキャッチされませんでした。

要約すると、そのクラスで使用している別の名前空間に別の例外タイプがありますか?

編集:これを確認する簡単な方法は、catch 句で例外タイプを「System.Exception」として完全に修飾し、それを試してみることです!

EDIT2: OK、コードを試してみましたが、今のところ敗北を認めています。誰も解決策を思いつかない場合は、午前中にもう一度確認する必要があります。

于 2008-09-02T16:00:45.823 に答える
2

私はあなたのコードをダウンロードし、すべてが期待どおりに動作します.

Visual Studio デバッガーは、すべての例外を正しくインターセプトします。キャッチ ブロックは期待どおりに機能します。

Windows 2003 サーバー SP2、VS2008 Team Suite (9.0.30729.1 SP) を実行しています。

プロジェクトを .NET 2.0、3.0、および 3.5 用にコンパイルしようとしました

@Steve Steiner、あなたが言及したデバッガーオプションは、この動作とは何の関係もありません。

私は目に見える効果なしでこれらのオプションを試してみました.catchブロックはすべての例外をインターセプトすることができました.

于 2008-09-03T05:44:32.970 に答える
2

私にとって、catch (Exception) 句は例外をすべてキャプチャする必要がありました。そうしない理由はありますか?

私が考えることができる唯一の可能性は、他の何かがあなたの前にそれをキャッチし、キャッチされていない例外のように見える方法でそれを処理しているということです (たとえば、プロセスを終了します)。

私のtry/catchブロックはそれをキャッチせず、代わりに未処理の例外として実行を停止します.

終了プロセスの原因を見つける必要があります。未処理の例外以外の可能性があります。"{,,kernel32.dll}ExitProcess" にブレークポイントを設定して、ネイティブ デバッガーを使用してみてください。次に、SOSを使用して、終了プロセスを呼び出しているマネージド コードを特定します。

于 2008-09-02T04:28:00.370 に答える
1

リフレクターを使用して外部アセンブリをトレースしましたが、スレッド化の形跡はまったく見つかりませんでした。

糸脱毛が見つからないからといって、糸脱毛がないわけではありません。

.NETには「スレッドプール」があります。これは、ほとんどアイドル状態の「スペア」スレッドのセットです。特定のメソッドは、スレッドプールスレッドの1つで実行されるため、メインアプリをブロックしません。

露骨な例はThreadPool.QueueUserWorkItemのようなものですが、 Delegate.BeginInvokeのように、スレッドプール内でそれほど明白に見えないものを実行できるものは他にもたくさんあります。

本当に、あなたはkibbeeが提案することをする必要があります。

于 2008-09-01T04:02:01.177 に答える
1

最適なオプションは、未処理のすべての例外を中断するようにVisual Studioを設定するように聞こえます([デバッグ]-> [例外]ダイアログで、[共通言語ランタイム例外]および場合によっては他の例外のチェックボックスをオンにします)。次に、プログラムをデバッグモードで実行します。ANTLRパーサーコードが例外をスローする場合、それはVisual Studioによってキャッチされ、発生している場所、例外の種類などを確認できるようにする必要があります。

説明に基づくと、catchブロックは正しいように見えるため、いくつかの原因の1つが発生している可能性があります。

  1. パーサーは実際には例外をスローしていません
  2. パーサーは最終的に、System.Exceptionから派生していないものをスローします。
  3. 処理されていない別のスレッドでスローされる例外があります

問題#3を除外した可能性があるようです。

于 2008-08-31T14:58:10.733 に答える
1

ビジュアルスタジオを使用せず、コンソールでアプリケーションを実行せずに、catch 句内で例外を出力 (Console.WriteLine()) しようとしましたか?

于 2008-09-02T15:45:25.173 に答える
1

例外が発生するとすぐに中断するように VS.Net を設定できます。プロジェクトをデバッグ モードで実行するだけで、例外がスローされるとすぐに停止します。そうすれば、なぜそれがキャッチされないのかをよりよく理解できるはずです。

また、未処理の例外をすべてキャッチするコードを追加することもできます。

Application.ThreadException += new ThreadExceptionEventHandler(ThreadExceptionHandler);

 // Catch all unhandled exceptions in all threads.
 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
于 2008-08-30T15:36:05.063 に答える
1

ああ、キビーが言ったことに関して。VSでDebug | Exceptionsを選択し、「thrown」列のすべてのボックスをクリックするだけで、AFAIKですべてを「最初の例外」として選択する必要があります。つまり、VSは、例外が他のすべてによって処理されようとしている時期を示します。関連するコードを中断します。これはデバッグに役立ちます。

于 2008-08-30T15:42:48.997 に答える
1

私はスティーブ・スタイナーが正しいと信じています。Steve の提案を調査しているときに、[ツール]、[オプション]、[デバッガ]、[全般] の [マイ コードのみを有効にする] オプションについて話しているこのスレッドに出くわしました。非ユーザー コードが例外をスローまたは処理すると、特定の状況でデバッガーが中断することが推奨されます。なぜこれが重要なのか、または実際には例外が処理されなかったとデバッガーが具体的に言う理由は正確にはわかりません。

「マイコードのみを有効にする」オプションを無効にすることで、誤ったブレークを排除することができました。これにより、「ユーザー処理」列が適用されなくなったため、「デバッグ | 例外」ダイアログも変更されます。または、CLR の [ユーザー処理] ボックスをオフにして、同じ結果を得ることができます。

みんな助けてくれてありがとう!

于 2008-09-03T10:17:12.927 に答える
0

うわー、これまでのレポートのうち、2つは正しく機能し、1つは私が報告した問題を経験しました。使用されているWindows、Visual Studio、およびビルド番号付きの.NET Frameworkのバージョンは何ですか?

XP SP2、VS 2008 Team Suite(9.0.30729.1 SP)、C#2008(91899-270-92311015-60837)、および.NET3.5SP1を実行しています。

于 2008-09-03T01:21:06.943 に答える
0

不明かどうかはわかりませんが、不明な場合は、デバッガーがNoViableAltExceptionタイプの「未処理の例外」で実行を停止しているのがわかります。最初は、この[デバッグ]-> [例外]メニュー項目について何も知りませんでした。MSは、VSのインストール時に、プロファイルがどのように異なるかわからないときにプロファイルにコミットすることを期待しているためです。どうやら、私はC#devプロファイルに参加しておらず、このオプションがありませんでした。スローされたすべてのCLR例外を最終的にデバッグした後、残念ながら、この未処理の例外問題の理由につながる新しい動作を見つけることができませんでした。スローされたすべての例外は予期されたものであり、おそらくtry/catchブロックで処理されます。

外部アセンブリを確認しましたが、マルチスレッドの証拠はありません。つまり、System.Threadingへの参照は存在せず、デリゲートはまったく使用されていません。私はそれがスレッドのインスタンス化を構成することをよく知っています。未処理の例外が発生したときにスレッドツールボックスを観察して、実行中のスレッドが1つしかないことを確認することで、これを確認します。

私はANTLRの人々と未解決の問題を抱えているので、おそらく彼らは以前にこの問題に取り組むことができたでしょう。VS2008およびVS2005で.NET2.0および3.5を使用して、単純なコンソールアプリプロジェクトで複製することができました。

これは、コードが既知の有効なパーサー入力でのみ機能するように強制するため、単なる問題点です。メソッドを使用するIsValid()と、ユーザー入力に基づいて未処理の例外がスローされた場合にリスクがあります。この問題についてさらに多くのことがわかったら、この質問を最新の状態に保ちます。

于 2008-09-02T14:08:43.860 に答える
0

私はダニエル・オージェクロノスに同意します。これは、スレッドに関係する例外のような匂いがします。それを超えて、ここに私の他の質問があります:

  1. 完全なエラーメッセージは何と言っていますか?どんな例外ですか?
  2. ここで提供したスタックトレースに基づいて、TimeDefLexer.mTokens()のコードで例外がスローされませんか?
于 2008-08-30T16:19:55.240 に答える
0

@スポールソン、

複製できたら、どこかに投稿できますか?試すことができる 1 つの方法は、SOS 拡張機能を備えた WinDBG を使用してアプリを実行し、未処理の例外をキャッチすることです。最初のチャンスの例外 (ランタイムがハンドラーを見つけようとする前) で中断し、その時点で、それがどこから来ているか、どのスレッドかを確認できます。

以前に WinDBG を使用したことがない場合は、少し圧倒されるかもしれませんが、ここに良いチュートリアルがあります。

http://blogs.msdn.com/johan/archive/2007/11/13/getting-started-with-windbg-part-i.aspx

WinDBG を起動したら、[デバッグ] -> [イベント フィルター] に移動して、未処理の例外の中断を切り替えることができます。

于 2008-09-02T14:30:56.630 に答える
0

「また、ハンドルされていないすべての例外をキャッチするコードを追加することもできます。詳細についてはリンクを参照してください。ただし、基本はこの 2 行です。」

これは誤りです。これは、.NET 1.0/1.1 ですべての未処理の例外をキャッチするために使用されていましたが、これはバグであり、想定されていなかったため、.NET 2.0 で修正されました。

AppDomain.CurrentDomain.UnhandledException 

プログラムが終了する前に例外をログに記録できるように、最後のチャンスのログサロンとしてのみ使用することを目的としています。2.0 以降では例外をキャッチしません (ただし、.NET 2.0 には、少なくとも 1.1 のように動作するように変更できる構成値がありますが、これを使用することはお勧めできません)。

StackOverflowException や OutOfMemoryException など、キャッチできない例外がいくつかあることに注意してください。それ以外の場合は、他の人が示唆しているように、どこかのバックグラウンド スレッドの例外である可能性があります。また、一部/すべてのアンマネージ/ネイティブ例外もキャッチできないと確信しています。

于 2008-08-30T16:04:42.657 に答える
0

わかりません...あなたのcatchブロックは新しい例外をスローするだけです(同じメッセージで)。つまり、あなたの声明は次のとおりです。

問題は、(すべてではありませんが) 場合によっては、try/catch ブロックがそれをキャッチせず、代わりに未処理の例外として実行を停止することです。

まさに起こると予想されることです。

于 2008-08-30T16:10:28.133 に答える
0

プロジェクトで com オブジェクトを使用していて、catch ブロックを試して例外をキャッチしない場合は、Tools/Debugging/Break when exceptions cross the AppDomain or managed/native boundary (Managed only) オプションを無効にする必要があります。

于 2017-02-17T09:19:39.177 に答える