6

Windbg (sos エクステンション付き) を使用しており、クラッシュしたアプリケーションをデバッグしようとしています。例外をスローした呼び出しの IL をダンプすることができ、コードを調べると、評価スタックの内容をダンプできれば必要な情報を取得できたようです。WinDbg & sos で何ができますか?

これが私がしたことです:

  1. WinDbgを開始しました
  2. クラッシュしたプロセスに接続
  3. loadby sos mscorwks (sos 拡張機能をロードするため)
  4. !token2ee theModuleName 0600009a (ここで、theModuleNameはデバッグ中のアプリ (およびアセンブリ) の名前で、9aは Windows エラー報告ツールによって報告されたクラッシュしたメソッドのメソッド オフセットです。次の出力が得られました。

    モジュール: 000e2c3c (theApplicationName.exe)
    トークン: 0x0600009a
    MethodDesc: 000e67c8
    名前: MyNamespace.MyClassName.theCulpritFn(MyOtherClass)
    JITTED コード アドレス: 0081b1d0

  5. !dumpil 00e67c8 (問題のメソッドの IL をダンプした) . これは出力です:

    
    // ..
    // .. the previous code omitted for brevity
    .catch
    {
     IL_0071: stloc.0
     IL_0072: nop
     IL_0073: ldstr "Can't set CurrentServer property for: "
     IL_0078: ldarg.0
     IL_0079: ldfld MyNamespace.MyClassName::_currentServer
     IL_007e: brtrue.s IL_0087
     IL_0080: ldstr ""
     IL_0085: br.s IL_0092
     IL_0087: ldarg.0
     IL_0088: ldfld MyNamespace.MyClassName::_currentServer
     IL_008d: callvirt MyNamespace.MyOtherClass::get_Name
     IL_0092: call System.String::Concat
     IL_0097: ldloc.0
     IL_0098: newobj MyNamespace.MySpecialExceptionType::ctor
     IL_009d: throw
    } 
    

    問題は、例外がスローされる前に何がスタックにプッシュされたかを確認する方法があるかどうかです。私が間違っていなければ、例外コンストラクターに渡される引数は、評価スタックのインデックス 0 にあるローカル変数でなければなりません。

    PS !clrstack -aを呼び出そうとすると、次のメッセージが表示されました。現在のスレッドはマネージド スレッドではない可能性があります。!threads を実行して、プロセス内のマネージド スレッドの一覧を取得できます。

ありがとう!

4

2 に答える 2

2

うわー、突き抜ける実際のダンプがなければ、これは難しいです。:-)

ここにいくつかの質問があります..そして、上記の回答に以前にリストされていなかったコマンドを1つ追加します..

質問:

  1. 未処理でプロセスが取り壊された最後の例外だけでなく、最初の例外をキャッチしていると確信していますか?

  2. 例外をスローしたスレッドのネイティブ コール スタックを確認できますか。
    注: RaiseException() への呼び出しまたはアクセス違反があるはずです。

  3. コードとはまったく関係のない非同期例外に注意してください。キャッチ ブロックに入る可能性があります。さらに悪いことに (Thread.AbortException/System.OutofMemoryException および... StackOverflowException :-)

さらに掘り下げるには、障害のあるスレッドで!dumpstackを実行します。出力は正確ではありませんが、スレッドのコール スタックをウォークするという驚くべき仕事を行い、運が良ければ、.cxr で例外を参照する@記号が表示され、メッセージ内の .exr。その場合は、.cxr -cxr-addressを実行して、例外チェーン内の最初の例外を確認できます。

ポイント: 質問を横道にそれているかもしれませんが、例外が WER を呼び出した場合、それが処理されず、プロセスがダウンした場合は、最初の呼び出し履歴をログに記録するか、以前の例外を内部例外として追加して、根本原因を特定できるようにすることができます。 .

ありがとう、アーロン

于 2009-02-22T00:44:46.017 に答える