奇怪的手柄泄漏

发布于 2024-11-02 15:12:34 字数 1904 浏览 5 评论 0原文

我的应用程序(基本应用程序是 MFC 与 C++/CLI 互操作,但它还包含大量 C#、Windows 窗体、WPF)存在句柄泄漏。应用程序启动后不久,我可以看到任务管理器中的句柄计数持续增长(以每秒 10 个新句柄的速度)。所以我使用 handles.exe 来看看它们是什么类型的句柄。我发现泄漏的句柄是进程句柄。它们是我的应用程序进程的进程句柄。

所以我想知道什么操作通常会为其运行的进程创建句柄。知道吗?你见过这样的事情吗?考虑到我无法使用调试 DLL 并且只能使用可以 xcopy 部署的工具,我还能做些什么来追踪泄漏。

更新:

我能够向它抛出windbg!handle,!htrace并发现该过程句柄都是使用以下堆栈跟踪(按频率排序)创建的:

0x79f7570b: mscorwks!CorExitProcess+0x00022055
0x79f03edd: mscorwks!GetPrivateContextsPerfCounters+0x0000b6fe
0x79f04b87: mscorwks!GetPrivateContextsPerfCounters+0x0000c3a8
0x79f04b03: mscorwks!GetPrivateContextsPerfCounters+0x0000c324
0x79f919bf: mscorwks!CorExitProcess+0x0003e309
0x79f91b28: mscorwks!CorExitProcess+0x0003e472
0x792d6b4c: mscorlib_ni+0x00216b4c
0x1391a663: +0x1391a663
0x1391a0b1: +0x1391a0b1
0x7a9ea544: System_ni+0x005aa544
0x792a842f: mscorlib_ni+0x001e842f

或者

0x7c8106f5: kernel32!CreateThread+0x0000001e
0x79f04bb2: mscorwks!GetPrivateContextsPerfCounters+0x0000c3d3
0x79f04b03: mscorwks!GetPrivateContextsPerfCounters+0x0000c324
0x79f919bf: mscorwks!CorExitProcess+0x0003e309
0x79f91b28: mscorwks!CorExitProcess+0x0003e472
0x792d6b4c: mscorlib_ni+0x00216b4c
0x1391a663: +0x1391a663
0x1391a0b1: +0x1391a0b1
0x7a9ea544: System_ni+0x005aa544
0x792a842f: mscorlib_ni+0x001e842f

或者

0x08ec2eba: +0x08ec2eba
0x792b8277: mscorlib_ni+0x001f8277
0x792b8190: mscorlib_ni+0x001f8190
0x792b8040: mscorlib_ni+0x001f8040
0x792b7ff2: mscorlib_ni+0x001f7ff2
0x677e48f3: System_Runtime_Remoting_ni+0x000748f3
0x677e44be: System_Runtime_Remoting_ni+0x000744be
0x677e46ec: System_Runtime_Remoting_ni+0x000746ec
0x677e8408: System_Runtime_Remoting_ni+0x00078408
0x7926eb8d: mscorlib_ni+0x001aeb8d

现在这告诉我什么?

My application (base application is MFC interop with C++/CLI but it also contains a lot of C#, Windows Forms, WPF) has has a handle leak. Shortly after application start I can see the handle count in the task manager grow continuously (at a rate of 10 new handles per second). So I used handles.exe to see what kind of handles they are. I found out that the leaking handles are process handles. And they are process handles to the process of my application.

So I wonder what operations would typically create a handle to the process it runs in. Any idea? Have you ever seen something like this? What else could I do to track down the leak, considering that I can't use debug DLLs and that I can only use tools that can be xcopy deployed.

Update:

I was able to throw windbg and !handle, !htrace at it and found out that the process handles are all created using the following stack traces (ordered by frequency):

0x79f7570b: mscorwks!CorExitProcess+0x00022055
0x79f03edd: mscorwks!GetPrivateContextsPerfCounters+0x0000b6fe
0x79f04b87: mscorwks!GetPrivateContextsPerfCounters+0x0000c3a8
0x79f04b03: mscorwks!GetPrivateContextsPerfCounters+0x0000c324
0x79f919bf: mscorwks!CorExitProcess+0x0003e309
0x79f91b28: mscorwks!CorExitProcess+0x0003e472
0x792d6b4c: mscorlib_ni+0x00216b4c
0x1391a663: +0x1391a663
0x1391a0b1: +0x1391a0b1
0x7a9ea544: System_ni+0x005aa544
0x792a842f: mscorlib_ni+0x001e842f

or

0x7c8106f5: kernel32!CreateThread+0x0000001e
0x79f04bb2: mscorwks!GetPrivateContextsPerfCounters+0x0000c3d3
0x79f04b03: mscorwks!GetPrivateContextsPerfCounters+0x0000c324
0x79f919bf: mscorwks!CorExitProcess+0x0003e309
0x79f91b28: mscorwks!CorExitProcess+0x0003e472
0x792d6b4c: mscorlib_ni+0x00216b4c
0x1391a663: +0x1391a663
0x1391a0b1: +0x1391a0b1
0x7a9ea544: System_ni+0x005aa544
0x792a842f: mscorlib_ni+0x001e842f

or

0x08ec2eba: +0x08ec2eba
0x792b8277: mscorlib_ni+0x001f8277
0x792b8190: mscorlib_ni+0x001f8190
0x792b8040: mscorlib_ni+0x001f8040
0x792b7ff2: mscorlib_ni+0x001f7ff2
0x677e48f3: System_Runtime_Remoting_ni+0x000748f3
0x677e44be: System_Runtime_Remoting_ni+0x000744be
0x677e46ec: System_Runtime_Remoting_ni+0x000746ec
0x677e8408: System_Runtime_Remoting_ni+0x00078408
0x7926eb8d: mscorlib_ni+0x001aeb8d

Now what does that tell me?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

苍白女子 2024-11-09 15:12:34

调用堆栈看起来不对。您是否正确设置了符号服务器? .symfix 在 Windbg 中应该可以解决问题。之后你应该得到更好的堆栈跟踪。

看起来存在此问题的部分代码是受管理的,因此在 DuplicateHandle 和 OpenProcess 上中断并转储那里的托管调用堆栈是有意义的。这两种方法是唯一可以产生真正的进程句柄的方法。

您可以像这样声明一个断点,并在命中断点时执行命令。
在这种情况下,将打印托管堆栈,然后继续执行。

bp kernel32!OpenProcess "!ClrStack;g"

The call stacks look wrong. Did you setup the symbol server correctly? .symfix should do the trick in Windbg. Afterwards you should get a better stacktrace.

It looks like part of the code that has this problem is managed so it would make sense to break on DuplicateHandle and OpenProcess and dump the managed call stack there. These two methods are the only ones which could produce a real process handle.

You can declare a breakpoint like this and execute commands when the breakpoint is hit.
In this case the managed stack is printed and then the execution does continue.

bp kernel32!OpenProcess "!ClrStack;g"
此刻的回忆 2024-11-09 15:12:34

通过互操作调用 COM 对象的 Web 服务也存在同样的问题。

我通过针对我创建的互操作对象显式调用 Marshal.ReleaseComObject 解决了这个问题。从那一刻起对我来说就没有问题了。

希望有帮助。

Had same issues with a webservice calling COM objects through interop.

I solved this by explicitely calling Marshal.ReleaseComObject against the interop objects I created. No issues after that moment for me.

Hope it helps.

北陌 2024-11-09 15:12:34

那么...您是否明确执行性能计数器(如果是这样,请尝试禁用它们以缩小泄漏源的范围)。

So... are you doing performance counters explicitely (if so, try disabling them to narrow down on the source of the leaks).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文