6

我在 C# 程序中有句柄泄漏。我正在尝试使用 WinDbg 使用 !htrace 对其进行诊断,大致如this answer中所述,但是当我在 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:/symbols http://msdl.microsoft.com/download/symbols;D :\Projects\Sandpit\bin\Debug;srv*

当我在 WinDbg 中打开可执行文件时,我没有收到任何错误。在输出目录(“D:\Projects\Sandpit\bin\Debug”)中有一个名为“Sandpit.pdb”的文件。该项目是在本地构建的,因此 pdb 文件应与 exe 匹配。我从这里下载了 WinDbg 。我在 Visual Studio 的项目设置中选中了“启用本机代码调试”。

4

1 回答 1

9

WinDbg 尝试尽可能地解释本机调用堆栈,但是要完全解释 CLR 应用程序的堆栈,WinDbg 需要使用名为SOS的扩展。这个扩展有一个单独的命令CLRStack用于查看 CLR 堆栈的堆栈信息。您需要先加载 SOS 扩展,但是使用.loadby sos clr命令(或类似命令,我记得要加载正确版本的 SOS 可能会有点痛苦)

有关更多信息,请参阅

于 2012-10-23T16:34:40.023 回答