我在C#程序中存在句柄泄漏。我試圖使用WinDbg使用!htrace進行診斷,大致如this answer中所示,但是當我在WinDbg中運行!htrace -diff時,出現堆棧跟蹤,它們沒有顯示我的C#函數的名稱(甚至我的.net程序集)。在WinDbg中顯示C#堆棧跟蹤時出現故障
我創建了一個小測試程序來說明我的困難。這個程序除了「泄漏」手柄外什麼都不做。
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:\項目\沙坑\ BIN \調試\ 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:/符號http://msdl.microsoft.com/download/symbols;D:\項目\沙坑\ BIN \調試; SRV *
我不當我在WinDbg中打開可執行文件時得到任何錯誤。在輸出目錄(「D:\ Projects \ Sandpit \ bin \ Debug」)中有一個名爲「Sandpit.pdb」的文件。該項目是在本地構建的,因此pdb文件應該與exe相匹配。我下載了WinDbg from here。我在Visual Studio的項目設置中選中了「啓用本地代碼調試」。
看着堆棧跟蹤是不會告訴你的是,列表存儲手柄。你需要看看堆。在Windbg中很痛苦,堆是一個巨大的消防水帶。請考慮使用.NET內存分析器。 –