c# - 在 WinDbg 中显示 C# 堆栈跟踪时出现问题

标签 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 中转到"file"->“打开可执行文件”并选择我的程序 (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 符号搜索路径是

SRVC:/symbolshttp://msdl.microsoft.com/download/symbols;D:\Projects\Sandpit\bin\Debug;srv*

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

最佳答案

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

更多信息见

关于c# - 在 WinDbg 中显示 C# 堆栈跟踪时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13035125/

相关文章:

windows - 为什么 windbg 命令以 .或者 !

.net - 在多个 .net 框架版本上使用 windbg

python - 获取导致异常的异常描述和堆栈跟踪,全部作为字符串

java - 生产环境 - http 500 错误页面 - 请没有堆栈跟踪

c# - SQLite 关键字 'OR' 附近的语法不正确

c# - 如何检测 C# 中的 Tab 键按下?

c# - const 字段是否在编译时转换为静态字段?

windows - 如何转储可执行文件的所有函数名称?

c# - Quartz.net 以何种格式存储时间

Objective-C - 命令行 (clang) - 打印堆栈跟踪