Discussion:
Windows 8 crash in EmumFontFamiliesEx
(too old to reply)
Andreas Hiltner
2013-03-11 14:45:39 UTC
Permalink
Did anyone notice a crash or non-standard beahvior when calling EnumFontFamiliesEx()?
My code works fine on Windows 7, Vista and before, but crashes on Windows 8 or just calls the callback-function just once.
The debugger tells me it's a corrupt heap, but the code is the same as before.

"(...)
LPLOGFONT lf = (LPLOGFONT) malloc (sizeof(*lf));
memset(lf, '\0', sizeof(*lf));
lf->lfFaceName = '\0';
lf->lfCharSet = DEFAULT_CHARSET;
HRESULT hr;
HDC hdc = GetDC(0);

hr = EnumFontFamiliesEx(hdc, lf, fontProc, 0, 0);
(...)"

fontProc is defined as EnumFontFamExProc and returns 1 to continue the enumeration.

Any comments?
Andreas Hiltner
2013-03-12 08:20:55 UTC
Permalink
here is the call stack

0:000:x86> kb
ChildEBP RetAddr Args to Child
00fbf014 777dbc07 c0000374 777ee1e8 00fbf058 ntdll_77700000!RtlReportCriticalFailure+0x33
00fbf024 777dac5d 00000002 29f01f97 011d0000 ntdll_77700000!RtlpReportHeapFailure+0x21
00fbf058 77775b9c 00000009 011d0000 00000001 ntdll_77700000!RtlpLogHeapFailure+0xa2
00fbf08c 7579edc9 011d0000 00000000 00000001 ntdll_77700000!RtlFreeHeap+0x6c
00fbf0e4 7579ee78 cc0117d6 00000000 00000001 GDI32!EnumFontsInternalW+0x166
00fbf108 5ecf43d0 cc0117d6 00e63638 011b0054 GDI32!EnumFontFamiliesExW+0x34

call stack without addresses

ntdll_77700000!RtlReportCriticalFailure+0x33
ntdll_77700000!RtlpReportHeapFailure+0x21
ntdll_77700000!RtlpLogHeapFailure+0xa2
ntdll_77700000!RtlFreeHeap+0x6c
GDI32!EnumFontsInternalW+0x166
GDI32!EnumFontFamiliesExW+0x34

any idea, what I'm doing wrong here?
David Lowndes
2013-03-14 17:07:17 UTC
Permalink
Post by Andreas Hiltner
Did anyone notice a crash or non-standard beahvior when calling EnumFontFamiliesEx()?
My code works fine on Windows 7, Vista and before, but crashes on Windows 8 or just calls the callback-function just once.
The debugger tells me it's a corrupt heap, but the code is the same as before.
The following works for me on Windows 8:

#include "stdafx.h"
#include <Windows.h>

int CALLBACK fontProc(
const LOGFONT *lpelfe,
const TEXTMETRIC *lpntme,
DWORD FontType,
LPARAM lParam
)
{
_tprintf( _T("%s\n"), static_cast<LPCTSTR>( lpelfe->lfFaceName
) );
return 1;
}

int _tmain(int argc, _TCHAR* argv[])
{
LPLOGFONT lf = (LPLOGFONT) malloc (sizeof(*lf));
memset(lf, '\0', sizeof(*lf));
lf->lfCharSet = DEFAULT_CHARSET;
HRESULT hr;
HDC hdc = GetDC(0);

hr = EnumFontFamiliesEx(hdc, lf, fontProc, 0, 0);
return 0;
}

Dave
c***@gmail.com
2014-07-09 13:47:21 UTC
Permalink
I'm getting the crash too.

I discovered however that it seems to only happen on a system with lots of fonts installed. I must have around 6000 fonts installed.

I'm trying to resolve this crash right now.
c***@gmail.com
2014-07-09 13:54:50 UTC
Permalink
Also, note that this does not seem to be a problem unless you call EnumFontFamiliesEx recursively too much.

In my case, I was calling it on 3 levels
1) EnumFontFamiliesEx (for font faces) - Typical
2) EnumFontFamiliesEx (for fonts) - Typical
3) EnumFontFamiliesEx (for super secret reasons) - Unusual.

I'll try to fix my problem by avoiding the triple recursion.
c***@gmail.com
2014-07-09 14:59:01 UTC
Permalink
Avoiding the triple recursion for me was not an option. Regardless, I was wrong about it.

I did a test and tried to call EnumFontFamiliesEx recursively 5 times and no problem so it had to be something else.

I finally found out that my callback was :
static int callback(const LOGFONT* lpelfe, const TEXTMETRIC* lpntme, DWORD FontType, LPARAM lParam);
instead of
static int CALLBACK callback(const LOGFONT* lpelfe, const TEXTMETRIC* lpntme, DWORD FontType, LPARAM lParam);

The wrong calling convention was used.

I missed it because the code was doing a C cast :
::EnumFontFamiliesEx(hdc, &logFontEnum, (FONTENUMPROCW)EnumFontFace::callback, reinterpret_cast<LPARAM>(this), 0);

Dont do that. Don't cast it. If you have to cast like this, your function signature is probably wrong like in my current case.
Deanna Earley
2014-07-09 15:34:39 UTC
Permalink
Post by c***@gmail.com
Avoiding the triple recursion for me was not an option. Regardless, I was wrong about it.
I did a test and tried to call EnumFontFamiliesEx recursively 5 times and no problem so it had to be something else.
static int callback(const LOGFONT* lpelfe, const TEXTMETRIC* lpntme, DWORD FontType, LPARAM lParam);
instead of
static int CALLBACK callback(const LOGFONT* lpelfe, const TEXTMETRIC* lpntme, DWORD FontType, LPARAM lParam);
The wrong calling convention was used.
::EnumFontFamiliesEx(hdc, &logFontEnum, (FONTENUMPROCW)EnumFontFace::callback, reinterpret_cast<LPARAM>(this), 0);
Dont do that. Don't cast it. If you have to cast like this, your function signature is probably wrong like in my current case.
I'll just leave this here :)
http://blogs.msdn.com/b/oldnewthing/archive/2011/05/06/10161590.aspx
--
Deanna Earley (***@icode.co.uk)
iCatcher Development Team
http://www.icode.co.uk/icatcher/

iCode Systems

(Replies direct to my email address will be printed, shredded then fed
to the rats. Please reply to the group.)
Loading...