如何诊断手柄泄漏?

我有一个托管WCF ServiceHost的进程。 根据ProcessExplorer,它会像疯了一样泄漏句柄。 我已经查看了代码,找不到任何明显导致泄漏句柄的内容。

我最接近的是ProcessExplorer提供的句柄列表,但其有用性似乎有限。 有没有其他工具可以帮助诊断手柄来自哪里,比如通过堆栈跟踪或什么?

编辑

我已经安装了Windbg。 当我用它来列出句柄时,它向我显示914句柄属于“事件”类型 –

如果我选择其中一些,并使用!handle xf输出,我在大多数情况下获得与此类似的输出:

 Type Event Attributes 0 GrantedAccess 0x1f0003 HandleCount 2 PointerCount 3 Object Specific Information Event Type Manual Reset Event is Set 

有没有办法进一步深入了解事件的更多信息?

对不起早期的错误答案(现已删除,显示)。

Windows调试工具包包括WinDbg和朋友。 WindDbg是一个像Visual Studio这样的完整调试器,但更精简,更精简,并且在很多方面都更有能力。 运行WinDbg,附加到您的进程(F6),然后在命令窗口中键入!handle 。 您将获得所有句柄和一些统计信息的列表。 如果你向上滚动并看到一个看起来可能是漏洞的!handle f ,你可以这样做!handle f来显示它的更多信息。 例如,在我的系统上附加到iexplore.exe:

 0:019> !handle 1bc f Handle 1bc Type Key Attributes 0 GrantedAccess 0x2001f: ReadControl QueryValue,SetValue,CreateSubKey,EnumSubKey,Notify HandleCount 2 PointerCount 3 Name \REGISTRY\USER\S-1-5-21-498032705-2416727736-2837886327-1001\Software\Microsoft\Windows\CurrentVersion\Internet Settings Object Specific Information Key last write time: 11:04:51. 9/4/2011 Key name Internet Settings 

编辑

要查找更多信息,可以使用!htrace windbg命令。 要使用它,请使用windbg附加到您的进程,然后键入!htrace -enable ,然后键入g以恢复该进程。 稍微练习一下这个过程,然后使用CTRL-Break (即CTRL-PauseCTRL-Break 。 输入!htrace -diff 。 您应该看到一个堆栈跟踪列表,显示打开句柄和打开时的调用堆栈。 如果您没有设置Windows符号,那么唯一有意义的地址将是您自己的代码 – 但这应该足以为您提供所需的线索。

  ModLoad: 00000000`75020000 00000000`7504d000 WINTRUST.dll ModLoad: 00000000`75160000 00000000`7527d000 CRYPT32.dll ModLoad: 00000000`757d0000 00000000`757dc000 MSASN1.dll (2fd0.1ce4): Break instruction exception - code 80000003 (first chance) ntdll!DbgBreakPoint: 00000000`77440530 cc int 3 0:019> !htrace -enable Handle tracing enabled. Handle tracing information snapshot successfully taken. 0:019> g (2fd0.2c88): Break instruction exception - code 80000003 (first chance) ntdll!DbgBreakPoint: 00000000`77440530 cc int 3 0:019> !htrace -diff Handle tracing information snapshot successfully taken. 0x360 new stack traces since the previous snapshot. Ignoring handles that were already closed... Outstanding handles opened since the previous snapshot: -------------------------------------- Handle = 0x000000000000070c - OPEN Thread ID = 0x0000000000000c44, Process ID = 0x0000000000002fd0 0x000000007744232a: ntdll!NtOpenThread+0x000000000000000a 0x0000000074c83910: wow64!whNtOpenThread+0x00000000000000a0 0x0000000074c6cf87: wow64!Wow64SystemServiceEx+0x00000000000000d7 0x0000000074bf2776: wow64cpu!TurboDispatchJumpAddressEnd+0x000000000000002d 0x0000000074c6d07e: wow64!RunCpuSimulation+0x000000000000000a 0x0000000074c6c549: wow64!Wow64LdrpInitialize+0x0000000000000429 0x000000007746e707: ntdll! ?? ::FNODOBFM::`string'+0x0000000000029364 0x000000007741c32e: ntdll!LdrInitializeThunk+0x000000000000000e 0x00000000775f113a: ntdll_775d0000!ZwOpenThread+0x0000000000000012 0x0000000075ea2e32: KERNELBASE!OpenThread+0x0000000000000049 0x00000000755578df: iertutil!CIsoMalloc::AllocArtifact+0x0000000000000050 0x00000000755578b4: iertutil!CIntraprocessMessageQueueSite::_QueryMessageThreadAffinityHelper_UntrustedSerializedIsoMessage+0x0000000000000055 0x0000000075557754: iertutil!CIntraprocessMessageQueueSite::QueryMessageThreadAffinity+0x000000000000004b -------------------------------------- Handle = 0x0000000000000790 - OPEN Thread ID = 0x00000000000019d4, Process ID = 0x0000000000002fd0 0x000000007744226a: ntdll!NtOpenKeyEx+0x000000000000000a 0x0000000074c8d205: wow64!Wow64NtOpenKey+0x0000000000000091 0x0000000074c8314f: wow64!whNtOpenKeyEx+0x0000000000000073 0x0000000074c6cf87: wow64!Wow64SystemServiceEx+0x00000000000000d7 0x0000000074bf2776: wow64cpu!TurboDispatchJumpAddressEnd+0x000000000000002d 0x0000000074c6d07e: wow64!RunCpuSimulation+0x000000000000000a 0x0000000074c6c549: wow64!Wow64LdrpInitialize+0x0000000000000429 0x000000007746e707: ntdll! ?? ::FNODOBFM::`string'+0x0000000000029364 0x000000007741c32e: ntdll!LdrInitializeThunk+0x000000000000000e 0x00000000775f101a: ntdll_775d0000!ZwOpenKeyEx+0x0000000000000012 0x0000000075ad2271: KERNEL32!LocalBaseRegOpenKey+0x000000000000010c 0x0000000075ad2416: KERNEL32!RegOpenKeyExInternalW+0x0000000000000130 0x0000000075ad2302: KERNEL32!RegOpenKeyExW+0x0000000000000021 -------------------------------------- Handle = 0x0000000000000788 - OPEN Thread ID = 0x00000000000019d4, Process ID = 0x0000000000002fd0 0x000000007744226a: ntdll!NtOpenKeyEx+0x000000000000000a 0x0000000074c8d205: wow64!Wow64NtOpenKey+0x0000000000000091 0x0000000074c8314f: wow64!whNtOpenKeyEx+0x0000000000000073 0x0000000074c6cf87: wow64!Wow64SystemServiceEx+0x00000000000000d7 0x0000000074bf2776: wow64cpu!TurboDispatchJumpAddressEnd+0x000000000000002d 0x0000000074c6d07e: wow64!RunCpuSimulation+0x000000000000000a 0x0000000074c6c549: wow64!Wow64LdrpInitialize+0x0000000000000429 0x000000007746e707: ntdll! ?? ::FNODOBFM::`string'+0x0000000000029364 0x000000007741c32e: ntdll!LdrInitializeThunk+0x000000000000000e 0x00000000775f101a: ntdll_775d0000!ZwOpenKeyEx+0x0000000000000012 0x0000000075ad2271: KERNEL32!LocalBaseRegOpenKey+0x000000000000010c 0x0000000075ad2416: KERNEL32!RegOpenKeyExInternalW+0x0000000000000130 0x0000000075ad2302: KERNEL32!RegOpenKeyExW+0x0000000000000021  

使用内存分析器 – 它们可以帮助查找此类泄漏,例如: