c# - 如何诊断句柄泄漏?

标签 c# wcf

我有一个托管 WCF ServiceHost 的进程。根据 ProcessExplorer,它会疯狂地泄漏句柄。我已经检查了代码,但找不到任何导致句柄泄漏的明显原因。

我能想到的最接近的是 ProcessExplorer 提供的句柄列表,但它的用处似乎有限。是否有任何其他工具可以帮助诊断句柄的来源,例如通过堆栈跟踪或其他工具?

编辑

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

如果我选择其中的一些,并使用 !handle x f 输出,我得到的输出与大多数情况类似:

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

有没有办法进一步挖掘以确定有关该事件的更多信息?

最佳答案

很抱歉之前的错误答案(现在已删除,看来)。

Windows 调试工具包包括 WinDbg 和它的 friend 。 WindDbg 是一个像 Visual Studio 一样的完整调试器,但更精简、更简洁,并且在许多方面更强大。运行 WinDbg,附加到您的进程 (F6),然后键入 !handle在命令窗口中。您将获得所有句柄的列表和一些统计信息。如果您向上滚动并看到一个看起来可能是泄漏的 handle 之一,您可以执行 !handle <handlenum> 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-Pause )。输入 !htrace -diff .您应该会看到一个堆栈跟踪列表,显示打开的句柄和打开它们时的调用堆栈。如果您没有设置 Windows 符号,唯一有意义的地址将是您自己的代码——但这应该足以让您获得所需的线索。

<snip>
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
<snip>

关于c# - 如何诊断句柄泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7617256/

相关文章:

c# - 代码契约和 MVVM

c# - 是否有在 UserNamePasswordValidator 之前调用的 WCF 扩展点?

c# - 网站和移动应用程序的成员(member)系统

.net - 跨 DMZ 的代理调用

asp.net - 在从 net.tcp 协议(protocol)连接到 WCF 的端点处监听的问题

c# - SQL 插入不工作

c# - 读取文件,搜索术语并替换该术语的所有行

c# - 在 Panel 而不是 DataGridView 上滚动

c# - 无法写入另一个进程 exp,多线程正忙的文件

c# - WCF 服务 :Fault Exceptions vs Error Message in Response Object