2011-10-01 104 views
9

我有一个托管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 

有没有办法深入挖掘以确定更多关于事件的信息?

+2

Visual Studio代码分析(或FxCop)会告诉你,如果你没有正确处置资源。 –

+0

约翰,我很好奇,你为什么把你的答案发表为评论而不是答案? –

+1

没想到这是一个很好的答案。我希望别人能够更好地完成这个想法。 –

回答

12

对不起,以前的错误答案(现在删除,它出现)。

Windows调试工具包包含WinDbg和朋友。 WindDbg是一个像Visual Studio一样的完整调试器,但是更精简,更方便,而且在很多方面都更加出色。运行WinDbg,附加到您的进程(F6),并在命令窗口中键入!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> 
+0

愚蠢的问题...我发现我认为是Windows包的调试工具,但安装后,没有提及WinDbg - 我从哪里正式安装来获取它? – bugfixr

+0

明白了,在安装调试工具之前必须先安装64位版本。 – bugfixr