GDI+ 泄漏检查






4.09/5 (8投票s)
2003年4月1日
2分钟阅读

78490

318
描述如何检查应用程序是否存在 GDI+ 泄漏。
引言
我们都知道 MFC 的内存泄漏检测,每个源代码文件的开头都有那个著名的 #define new DEBUG_NEW
。但对于 GDI+ 来说,之前并没有类似的功能,直到现在!
- 你需要 GDI+ 的 checked 版本,它位于 Checked Windows XP CD 的 ASMS\1000\MSFT\WINDOWS\GDIPLUS 文件夹中。
- 你需要构建一个不包含 manifest 的应用程序版本(调试或发布)。最快的方法是在 manifest 的属性中添加一个符号,使其不包含在构建中。如果你的应用程序没有 manifest,那就不用担心。
- 从 这里 安装 WinDGB(或者在 MSDN 上搜索“Debugging Tools”)。
- 复制你的可执行文件,并在名称后附加 .local,使其看起来像这样 - MyProj.exe.local
- 将 checked(也称为 debug)版本的 GDIPLUS.DLL 复制到你的项目可执行文件目录。
- 现在运行 WinDBG,选择“File/Open Executable...”并打开 EXE 文件,然后按 F5 并运行你的应用程序。
注意:确保 GDIPLUS.DLL 从你的项目目录加载,通过在 WinDBG 中验证加载的模块列表来确认。
当你运行应用程序一段时间后,退出并观察 WinDBG 中的输出。泄漏将显示如下:-
WRN mem.cpp(385): Address- --Size-- API TAG -Caller- -Line- File
WRN mem.cpp(406): 00D36AA0 584 unkn 00D36AAC 91 engine\runtime\mem.h
<=== LEAK!!!!!
WRN mem.cpp(406): 00D368E0 424 unkn 00D368EC 91 engine\runtime\mem.h
WRN mem.cpp(406): 00D367A0 296 API unkn 00D367AC 12191 engine\flat\flatapi.cpp
WRN mem.cpp(406): 00D36388 584 unkn 00D36394 91 engine\runtime\mem.h
WRN mem.cpp(406): 00D361C8 424 unkn 00D361D4 91 engine\runtime\mem.h
WRN mem.cpp(406): 00D36088 296 API unkn 00D36094 12191 engine\flat\flatapi.cpp
RIP mem.cpp(422): Memory leaks detected.
List header (gdiplus!gpmemAllocList) at 00D36AA0
Use: dt AllocTrackHeader [address] to display the memory block headers.
Use: dds [AllocTrackHeader.caller_address] to display the allocation stack.
(此输出是由本文包含的示例项目生成的。我分配了一个 Pen,但没有释放它。)
要找到此泄漏的源代码位置,只需使用 dds 命令,后跟 -Caller- 地址,如下所示...
dds 00D36AAC
WinDBG 将找到代码位置并报告如下:-
0:000> dds 00D36AAC
00d36aac 6f6b798a gdiplus!GdipCreateSolidFill+0xcabac
00d36ab0 6f5fff97 gdiplus!GdipCreateSolidFill+0x131b9
00d36ab4 6f5ea816 gdiplus!GdipCreatePen1+0xcf
00d36ab8 004158ed*** WARNING: Unable to verify checksum for MyProj.exe
MyProj!Gdiplus::Pen::Pen+0x4d
[c:\vc7\vc7\platformsdk\include\prerelease\gdipluspen.h @ 33]
00d36abc 00415685 MyProj!CChildView::OnPaint+0xb5
[c:\projects\collage\docs\article\myproj\childview.cpp @ 50]
00d36ac0 7c1feedf MFC70D!CWnd::OnWndMsg+0x796
[f:\vs70builds\9466\vc\mfcatl\ship\atlmfc\src\mfc\wincore.cpp @ 2015]
00d36ac4 7c1fe71f MFC70D!CWnd::WindowProc+0x2e
[f:\vs70builds\9466\vc\mfcatl\ship\atlmfc\src\mfc\wincore.cpp @ 1737]
00d36ac8 7c1fc11a MFC70D!AfxCallWndProc+0xe0
[f:\vs70builds\9466\vc\mfcatl\ship\atlmfc\src\mfc\wincore.cpp @ 241]
如上图所示,此泄漏发生在 ChildView.cpp 的第 50 行。你应该修复该泄漏并重复该过程,直到删除所有泄漏。
历史
2003-03-12 - 创建