6

C#プログラムでハンドルリークが発生しました。おおまかにこの回答に示されているように、!htraceを使用してWinDbgを使用して診断しようとしていますが、WinDbgで!htrace -diffを実行すると、C#関数の名前が表示されないスタックトレースが表示されます(または私の.netアセンブリでさえ)。

私は自分の難しさを説明するために小さなテストプログラムを作成しました。このプログラムは、「リーク」ハンドル以外は何もしません。

class Program
{
    static List<Semaphore> handles = new List<Semaphore>();

    static void Main(string[] args)
    {
        while (true)
        {
            Fun1();
            Thread.Sleep(100);
        }
    }

    static void Fun1()
    {
        handles.Add(new Semaphore(0, 10));            
    }
}

アセンブリをコンパイルしてから、WinDbgで[ファイル]-> [実行可能ファイルを開く]に移動し、プログラム(D:\ Projects \ Sandpit \ bin \ Debug \ Sandpit.exe)を選択します。プログラムの実行を続行して中断し、「!htrace -enable」を実行してから、もう少し長く続けてから、中断して「!htrace-diff」を実行します。これは私が得るものです:

0:004> !htrace -enable
Handle tracing enabled.
Handle tracing information snapshot successfully taken.
0:004> g
(1bd4.1c80): Break instruction exception - code 80000003 (first chance)
eax=7ffda000 ebx=00000000 ecx=00000000 edx=77b2f17d esi=00000000 edi=00000000
eip=77ac410c esp=0403fc20 ebp=0403fc4c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!DbgBreakPoint:
77ac410c cc              int     3
0:004> !htrace -diff
Handle tracing information snapshot successfully taken.
0xd new stack traces since the previous snapshot.
Ignoring handles that were already closed...
Outstanding handles opened since the previous snapshot:
--------------------------------------
Handle = 0x00000250 - OPEN
Thread ID = 0x00001b58, Process ID = 0x00001bd4

0x77ad5704: ntdll!ZwCreateSemaphore+0x0000000c
0x75dcdcf9: KERNELBASE!CreateSemaphoreExW+0x0000005e
0x75f5e359: KERNEL32!CreateSemaphoreW+0x0000001d
*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\System\13c079cdc1f4f4cb2f8f1b66c8642faa\System.ni.dll
0x65d7e805: System_ni+0x0020e805
0x65d47843: System_ni+0x001d7843
0x65d477ef: System_ni+0x001d77ef
0x004700c9: +0x004700c9
0x67d73dd2: clr!CallDescrWorkerInternal+0x00000034
0x67d9cf6d: clr!CallDescrWorkerWithHandler+0x0000006b
0x67d9d267: clr!MethodDescCallSite::CallTargetWorker+0x00000152
0x67eb10e0: clr!RunMain+0x000001aa
0x67eb1200: clr!Assembly::ExecuteMainMethod+0x00000124
--------------------------------------
Handle = 0x0000024c - OPEN
Thread ID = 0x00001b58, Process ID = 0x00001bd4

0x77ad5704: ntdll!ZwCreateSemaphore+0x0000000c
0x75dcdcf9: KERNELBASE!CreateSemaphoreExW+0x0000005e
0x75f5e359: KERNEL32!CreateSemaphoreW+0x0000001d
0x65d7e805: System_ni+0x0020e805
0x65d47843: System_ni+0x001d7843
0x65d477ef: System_ni+0x001d77ef
0x004700c9: +0x004700c9
0x67d73dd2: clr!CallDescrWorkerInternal+0x00000034
0x67d9cf6d: clr!CallDescrWorkerWithHandler+0x0000006b
0x67d9d267: clr!MethodDescCallSite::CallTargetWorker+0x00000152
0x67eb10e0: clr!RunMain+0x000001aa
0x67eb1200: clr!Assembly::ExecuteMainMethod+0x00000124
...
--------------------------------------
Displayed 0xd stack traces for outstanding handles opened since the previous snapshot.

ご覧のとおり、スタックトレースには、C#関数名「Main」と「Fun1」がありません。「System_ni+0x ...」フレームが私の関数フレームかもしれないと思いますが、わかりません。私の質問は、WinDbgでC#関数の関数名をスタックトレースに表示するにはどうすればよいですか?

追加情報:私のWinDbgシンボル検索パスは

SRV C:/ symbol http://msdl.microsoft.com/download/symbols ; D: \ Projects \ Sandpit \ bin \ Debug; srv *

WinDbgで実行可能ファイルを開いても、エラーは発生しません。出力ディレクトリ(「D:\ Projects \ Sandpit \ bin \ Debug」)に「Sandpit.pdb」というファイルがあります。プロジェクトはローカルでビルドされるため、pdbファイルはexeと一致する必要があります。ここからWinDbgをダウンロードしました。VisualStudioのプロジェクト設定で[ネイティブコードのデバッグを有効にする]をオンにしました。

4

1 に答える 1

9

WinDbgは、ネイティブの呼び出しスタックを可能な限り解釈しようとしますが、CLRアプリケーションのスタックを完全に解釈するには、WinDbgはSOSと呼ばれる拡張機能を使用する必要があります。この拡張機能には、CLRStackCLRスタックのスタック情報を表示するための個別のコマンドがあります。最初にSOS拡張機能をロードする必要がありますが、.loadby sos clrコマンドを使用します(または同様の方法で、正しいバージョンのSOSをロードするのは少し面倒かもしれません)

詳細については、を参照してください。

于 2012-10-23T16:34:40.023 に答える