65.9K
CodeProject 正在变化。 阅读更多。
Home

GDI+ 泄漏检查

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.09/5 (8投票s)

2003年4月1日

2分钟阅读

viewsIcon

78490

downloadIcon

318

描述如何检查应用程序是否存在 GDI+ 泄漏。

引言

我们都知道 MFC 的内存泄漏检测,每个源代码文件的开头都有那个著名的 #define new DEBUG_NEW。但对于 GDI+ 来说,之前并没有类似的功能,直到现在!

  1. 你需要 GDI+ 的 checked 版本,它位于 Checked Windows XP CD 的 ASMS\1000\MSFT\WINDOWS\GDIPLUS 文件夹中。
  2. 你需要构建一个不包含 manifest 的应用程序版本(调试或发布)。最快的方法是在 manifest 的属性中添加一个符号,使其不包含在构建中。如果你的应用程序没有 manifest,那就不用担心。

    (点击 这里 阅读关于 manifest 的内容,或者在 MSDN 上搜索“Manifest Resources”。)
     
  3. 这里 安装 WinDGB(或者在 MSDN 上搜索“Debugging Tools”)。
  4. 复制你的可执行文件,并在名称后附加 .local,使其看起来像这样 - MyProj.exe.local
  5. 将 checked(也称为 debug)版本的 GDIPLUS.DLL 复制到你的项目可执行文件目录。
  6. 现在运行 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 - 创建

© . All rights reserved.