【发布时间】:2016-12-29 15:20:26
【问题描述】:
我对我的应用程序进行了通宵压力测试,当我今天早上进来时,软件因 Windows 错误而崩溃。
由于进程明显没有 GDI 句柄而发生错误:
进程浏览器
任务管理器
接下来要弄清楚我泄漏了哪种 GDI 资源(例如笔、画笔、位图、字体、区域、DC)。为此我转向NirSoft的GDIView:
- 笔: 0
- 外接笔:0
- 刷子:4
- 位图:35
- 字体:19
- 调色板:1
- 地区:3
- DC:11
- 元文件 DC:0
- 增强的元文件 DC:0
- 其他 GDI:0
- GDI 总数:0
- 所有 GDI:10,000
GDI 句柄可能是什么,不是任何已知的 GDI 类型?
【问题讨论】:
-
这在我看来就像 GDIView 中的一个错误,或者至少是一些非常出乎意料的事情。 “GDI Total”为0,但显然总数不应为0,因为有画笔、位图、字体等,更不用说它在“All GDI”下计算的10,000个句柄。我从来没有使用过这个应用程序,所以我不确定它是如何工作的或者它可能意味着什么。我只会使用 WinDbg,
dt ntdll!_PEB来确定 GdiSharedHandleTable 在 PEB 中的位置,然后查看它包含的句柄。你也可以试试Feng Yuan's GDIObj。 -
根据 GDIView 的documentation,“GDI Total”应该包括上面所有值的计数,但显然不是,我对此没有任何解释.但是,它确实说“All GDI”显示的计数是通过调用
GetGuiResources获得的,更有趣的是,“如果你有一个问题,'All GDI' 值增加,而没有泄漏使用其他 GDI 值,这意味着您可能在创建图标或光标时存在泄漏(创建图标和光标时不会稍后销毁它们)。” -
这是文档中的一个奇怪评论。图标和光标是User Objects,而不是GDI Objects。还是我在这里遗漏了什么?
-
列表中提到了元文件 DC,但 HMETAFILE 或 HENHMETAFILE 对象呢?
-
我会寻找不一定是泄漏的错误。例如,在共享 GDI 对象上调用 DestroyObject,或者在销毁或释放/销毁 DC 之前忘记从 DC 中选择 GDI 对象。我还会考虑暂时降低 GDI 对象配额,以便能够更快地重现问题。我还通过禁用 UI 功能并将它们重新添加到问题再次出现来搜索此类问题。
标签: winapi gdi resource-leak