Introduction
We all know about MFC's memory leak detection, that famous #define new DEBUG_NEW
at the beginning of each
source code file. But there's nothing similar for GDI+, until now!
- You'll need the checked build of GDI+, which is found in the
ASMS\1000\MSFT\WINDOWS\GDIPLUS folder of the Checked Windows XP CD.
- You'll need to build a version (debug or release) of your app WITHOUT the
manifest. The quickest way to do this is to simply add a symbol in the
properties for the manifest so it isn't included in the build. If your
app doesn't have a manifest, then just don't worry.
(Click
here to read about manifests, or search for the text Manifest Resources
on MSDN.)
- Install WinDGB from
here (or
search for the text Debugging Tools on MSDN)
- Create a copy of your executable and append .local to the name, so it
looks like this - MyProj.exe.local
- Copy the checked (also know as debug) version of GDIPLUS.DLL to
your project's executable directory.
- Now run WinDBG and go to "File/Open Executable..." and open the EXE, then
hit F5 and play with your app.
Note: Make sure that GDIPLUS.DLL is loaded
from your project's directory by verifying the loaded modules list in WinDBG.
Once you've played with the app for a while, exit and observe the output in
WinDBG. Leaks will be shown like this :-
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.
(This output was generated by the sample project included with
this article. I allocate a Pen, but never release it.)
To find
the source code location of this leak, simply use the dds command followed by
the -Caller- address, like this...
dds 00D36AAC
WinDBG will then find the code location and report it like this :-
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]
As you can see by the highlighted code above, this leak took place at line 50
of ChildView.cpp. You should now fix that leak and repeat the process
again, until all leaks are removed.
History
2003-Mar-12 - Created