4

Windbgを使用してマネージコード(C#、任意のCPU用に構築されたコンソールアプリケーション)からクラッシュダンプをロードしています。クラッシュダンプはx64プラットフォームで作成されます。x64プラットフォームでデバッグしています。

次のコマンドを使用して、アプリケーションのプライベートシンボルをロードしています。Windbgで使用しているコマンドは次のとおりです。

(set symbol path and copy FooService.pdb pdb file to local symbol path D:\Debug)

0:016> .reload /f
.*** WARNING: Unable to verify checksum for FooService.exe
DBGHELP: FooService.pdb- private symbols & lines 
         D:\Debug\FooService.pdb

0:016> lm
start             end                 module name
00000000`00400000 00000000`0041c000   FooService C (private pdb symbols)  D:\Debug\FooService.pdb

私の混乱は、次のコマンドを使用すると、スタックトレースに行番号情報が表示されないことです。何が悪いのか考えてみませんか?ソースパスを設定する必要がありますか?

0:016> ~6 e!clrstack

編集1:例外がスローされたスタックトレースを見つけるために!peと!Uを使用する際にいくつかの問題が発生しました。

これが私のデバッグプロセスです。最初に!peを使用して例外オブジェクトのスタックトレースを出力し、!Uを使用してコードを逆アセンブルします。私が見つけた問題は、!UがFooService.ProcessOrders()のすべての関数コードを分解することです。関数FooService.ProcessOrdersでクラッシュが発生する正確な場所を見つけたいと思います。また、分解された注釈付きILコードには、私が行った関数呼び出しのみが含まれ(非関数呼び出しC#コードの場合、たとえばa = a * 2の場合、アセンブリ言語のみが表示されます)、C#コードの各行に正確にILがマップされていません( 1)それは正しい期待される動作ですか?(2)ここに投稿された私の分析から正確に失敗したC#コードを見つけるための解決策またはさらなる提案は何ですか?

!pe 0000064280155325

StackTrace (generated):
    SP               IP               Function

    000000001A56DA70 00000642B74E3B7A System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(System.Data.Common.DbAsyncResult, System.String, Boolean)
    000000001A56DB10 00000642B74E3FCC System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
    000000001A56DB90 0000064280155325 FooService.ProcessOrders()
    000000001A56F3E0 0000064280153A21 FooService.RountineJob()

!U 0000064280155325 

事前に感謝します、ジョージ

4

1 に答える 1

6

WinDbg/SOS は、行番号を の出力にマップしません!clrstacklmしたがって、自分のアセンブリ用のプライベート pdb シンボルがあることを示している限り、セットアップは正しいです。残念ながら、WinDbg/SOS の現在のバージョンは、ネイティブ コードと同じ範囲でソース レベルのデバッグをサポートしていません。

編集:例外について。を実行する!peと、コール スタックと関連するメソッドへのオフセットが表示されます。!pe出力の IP 列からアドレスを取得し!Uてそれに対して実行すると、関連するメソッドの JITTED コードが表示されます。IP 列は、例外を生成したコードの最後のアドレスになります (そのため、正しい命令を見つけるために少しカウントする必要があります)。

逆アセンブルされた出力には .NET 呼び出しの注釈が付けられているため、これを IL またはソース コードに対してマッピングすることは難しくありません。これは、探している throw ステートメントを正確に特定するのに役立ちます。

そうは言っても、メソッドをいくつかの小さなメソッドに分割すると、デバッグがずっと簡単になります。その場合、通常はメソッド名で例外の場所を特定できます。それが常に選択肢であるとは限りませんが、検討する価値はあります。

于 2009-10-12T08:01:11.883 に答える