8

作成したWindowsサービスのダンプがあります。例外は、私のコードがファイルを移動できないことです(何らかの理由で)。さて、私のコードには、ファイルシステム内でファイルを移動する場所がいくつかあります。したがって、Windbgを使用して、例外が発生するコードを確認しようとしています。

これが私の!clrstackダンプです。

0:016> !clrstack -p
OS Thread Id: 0xdf8 (16)
Child-SP         RetAddr          Call Site
0000000019edea70 0000064278a15e4f System.IO.__Error.WinIOError(Int32, System.String)
PARAMETERS:
    errorCode = <no data>
    maybeFullPath = <no data>

0000000019edead0 0000064280181ce5 System.IO.File.Move(System.String, System.String)
PARAMETERS:
    sourceFileName = <no data>
    destFileName = <no data>

0000000019edeb50 0000064280196532 MyClass.Foo.DoSomeStuffInHere(System.String)
PARAMETERS:
    this = 0x0000000000c30aa8
    filePathAndName = 0x0000000000d1aad0

今、これは大いに役立ちます...

0:016> !do 0x0000000000d1aad0
Name: System.String
MethodTable: 00000642784365e8
EEClass: 000006427803e4f0
Size: 88(0x58) bytes
(C:\WINDOWS\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String: C:\BlahBlahFolder\FooFolder\4469.jpg
Fields:
-snipped-

だから私は移動に失敗したファイルを見つけました。ケウル。しかし、File.Move(..)を呼び出すこのメソッドMyClass.Foo.DoSomeStuffInHere(System.String)のコードを見たいだけです。そのメソッドにはたくさんのFile.Move..があるので、try / catchs / debug / trace information ..を置くことができますが、Windbgを使用してこの問題を見つけることで、より効率的になることを望んでいます。

何かご意見は?

4

2 に答える 2

3

アプリケーションがデバッグモードでデプロイされていない限り、正確なコード行を取得することはできません。その場合は、!clrstack呼び出しでそれらが表示されると思います。

于 2008-10-31T01:28:59.347 に答える
3

これは難しい問題であり、管理されたデバッグのみのコンフォート ゾーンの外に出る必要がある場合があります。

あなたがしたいことは、関数MyClass.Foo.DoSomeStuffInHereの IL をその関数の逆アセンブリにマップすることです。以下の例は x86 ですが、x64 でも同じ手順を実行できます。

これは、次のリンクの奥深くで参照されています。 予期しないプロセスの終了のデバッグ

ホワイトペーパーのテキスト例: マネージ スタックでは、Debugging.Unexpected.btnSTA_Click ... Debugging.Unexpected.btnSTA_Click イベントのコードを見てください。

private void btnSTA_Click(object sender, System.EventArgs e)
{
   DebuggingCOMLib.STAClass staobj =  new DebuggingCOMLib.STAClass();
   staobj.RaiseError(1,5);
   Label1.Text += "STA Call Completed sucessfully";
}

ソース コードが利用できない場合は、コール スタック フレームの命令ポインターを!u コマンドに指定して、アセンブリを調べることができます。命令ポインターは、!clrstack: 出力から取得できます。

0096f970  03a00e06 [DEFAULT] [hasThis] Void
Debugging.Unexpected.btnSTA_Click(Object,Class System.EventArgs)

この関数を逆アセンブルするには、!u 03a00e06と入力します。

    0:010> !u 03a00e06 
    Normal JIT generated code
    [DEFAULT] [hasThis] Void Debugging.Unexpected.btnSTA_Click(Object,Class 
    System.EventArgs)
    Begin 03a00de0, size 54
   <snip>
    03a00e18 8b15a89c1702     mov     edx,[02179ca8] ("STA Call Completed 
    sucessfully")
    03a00e1e e83d3590ff       call    03304360 (System.String.Concat)
    <snip>
    03a00e2f 5e               pop     esi
    03a00e30 5f               pop     edi
    03a00e31 c20400           ret     0x4

わかりました、今何ですか?
独自の !u 出力をスキャンして、次のような行を探します

call    03304360 (System.IO.File.Move)

また、!ip2md 03a00e06を実行して MethodDesc を取得してから、!dumpilを実行して IL コードを調べることもできます。

!u 出力でSystem.IO.File.Moveへの呼び出しの数を数え、IL で同じ数を数えることができます。次に、.NET Reflector を使用してメソッドを逆アセンブルし、C# を IL にマップして結果を比較できます。

多くの手順がありますが、同じ結果が得られます:-)

ありがとう、アーロン

于 2009-02-21T23:14:41.117 に答える