2012-10-23 72 views
5

我在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的項目設置中選中了「啓用本地代碼調試」。

+0

看着堆棧跟蹤是不會告訴你的是,列表存儲手柄。你需要看看堆。在Windbg中很痛苦,堆是一個巨大的消防水帶。請考慮使用.NET內存分析器。 –

回答

6

WinDbg嘗試儘可能地解釋本地調用堆棧,但要完全解釋CLR應用程序的堆棧,WinDbg需要使用名爲SOS的擴展名。該擴展有一個單獨的命令CLRStack用於查看CLR堆棧的堆棧信息。您需要先加載SOS擴展然而使用.loadby sos clr命令(或類似的,我記得我得到正確的版本SOS加載可能是一個有點痛)

欲瞭解更多信息,請參閱

+2

謝謝!這解釋了我爲什麼如此困惑。我讀過關於sos.dll的文章,但我錯誤地認爲它只是需要加載像htrace這樣的命令才能與CLR一起工作。通過使用'!htrace'然後''u'與堆棧地址,我已經接近了解決方案。這似乎也遇到了跨越p-invoke框架的問題,所以我在htrace返回的一個點處設置了一個斷點,並使用'!clrstack'來查看完整的CLR堆棧。 – Mike