I ran an overnight stress test of my application, and when i came in this morning the software had crashed from a Windows error.
The error occurred because the process was obviously out of GDI handles:
Process Explorer
Task Manager
The next thing is to figure out exactly which kind of GDI resource (e.g. Pen, Brush, Bitmap, Font, Region, DC) i'm leaking. For that i turned to NirSoft's GDIView:
- Pen: 0
- Ext Pen: 0
- Brush: 4
- Bitmap: 35
- Font: 19
- Palette: 1
- Region: 3
- DC: 11
- Metafile DC: 0
- Enhanced Metafile DC: 0
- Other GDI: 0
- GDI Total: 0
- All GDI: 10,000
What could a GDI handle be, one that is not any known GDI type?
The answer was GDI
HFONT
handles.It is a Windows 8 issue that GDIView cannot show the font handles.
I used hooking to intercept every call to:
and logged every handle creation, along with its stack trace of when it was allowed. At the end i created a report of all undeleted
HFONT
s.How did i do it?
I used the Detours library for Delphi.
Step 1 - For every GDI function there is that creates something, we ask Detours to intercept the function.
Step 2 - Declare our versions of the GDI functions:
Step 3 - Add code to track every font created by CreateFont, and every font destruction by DestroyObject
And then the
GdiLeakTrackerSvc
service tracks all font creations, font destructions, and can let us know during program shutdown if anything leaked.