无法在WinDbg中显示C#堆栈跟踪

时间:2012-10-23 16:30:16

标签: c# windbg stack-trace handle-leak

我在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中我去了“文件” - &gt; “打开可执行文件”并选择我的程序(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:/符号 http://msdl.microsoft.com/download/symbols;D:\项目\沙坑\ BIN \调试; SRV *

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

1 个答案:

答案 0 :(得分:7)

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

有关详细信息,请参阅