The small attached program blows up in FcFini() when it is run on
Ubuntu 12.04.1 LTS. It does not explode
on Mingw. On Ubuntu built it like:
gcc -Wall -g -I/usr/include/freetype2 -o ft_example ft_example.c
-lfreetype -lfontconfig
The mode of failure is:
gdb ./ft_example
run
...
letter:r advance = 1408
letter:l advance = 960
letter:d advance = 2368
ft_example: fccache.c:507: FcCacheFini: Assertion `fcCacheChains[i] ==
((void *)0)' failed.
Program received signal SIGABRT, Aborted.
0x00132416 in __kernel_vsyscall ()
(gdb) bt
#0 0x00132416 in __kernel_vsyscall ()
#1 0x0022f1ef in __GI_raise (sig=6) at
../nptl/sysdeps/unix/sysv/linux/raise.c:64
#2 0x00232835 in __GI_abort () at abort.c:91
#3 0x00228095 in __assert_fail_base (fmt=0x3618b8 "%s%s%s:%u:
%s%sAssertion `%s' failed.\n%n", assertion=0x1ec300 "fcCacheChains[i] ==
((void *)0)",
file=0x1ec347 "fccache.c", line=507, function=0x1ec382
"FcCacheFini") at assert.c:94
#4 0x00228147 in __GI___assert_fail (assertion=0x1ec300
"fcCacheChains[i] == ((void *)0)", file=0x1ec347 "fccache.c", line=507,
function=0x1ec382 "FcCacheFini") at assert.c:103
#5 0x001d2bae in ?? () from /usr/lib/i386-linux-gnu/libfontconfig.so.1
#6 0x001df3bb in FcFini () from
/usr/lib/i386-linux-gnu/libfontconfig.so.1
#7 0x08048d2f in main () at ft_example.c:127
When run under valgrind
valgrind --leak-check=yes --show-reachable=yes ./ft_example >vg.log
2>&1
there are multiple invalid reads before the printf's in the test
program and the leak summary is:
==10745== LEAK SUMMARY:
==10745== definitely lost: 640 bytes in 2 blocks
==10745== indirectly lost: 3,100 bytes in 154 blocks
==10745== possibly lost: 0 bytes in 0 blocks
==10745== still reachable: 64 bytes in 3 blocks
==10745== suppressed: 0 bytes in 0 blocks
Software Version info:
ubuntu 12.04.1 LTS
gcc 4.6.3
libfontconfig 2.8.0-3ubuntu9.1 (also tried building fontconfig 2.10.1
and linking to that, same problem)
libfreetype6 2.4.8-1ubuntu2 (probably irrelevant, all of the FT
parts could be removed with an #if 0
and FcFini() still blew up.
Both the mingw and Ubuntu machines were running on the same type of
hardware, using AMD Athlon II X2 245
processors.
Does this issue look familiar? Suggestions? The function that this
will go into needs to be absolutely clean when
run inside valgrind. The function will eventually be going into
Inkscape, which is already painful to use with valgrind,
and more spurious memory warnings must be avoided like the plague.
And, of course, the crash on FcFini() is
really a problem.
Thank you,
David Mathog
mathog@xxxxxxxxxxx
Manager, Sequence Analysis Facility, Biology Division, Caltech
#include <stdlib.h>
#include <stdio.h>
#include <ft2build.h>
#include <fontconfig/fontconfig.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#ifdef WIN32
#define ARIALFILE "C:\\WINDOWS\\Fonts\\arial.ttf"
//this does NOT work! #define ARIALFILE "/c/WINDOWS/Fonts/arial.ttf"
#else
#define ARIALFILE "/usr/share/fonts/truetype/msttcorefonts/arial.ttf"
#endif
/*
on Windows compile like:
gcc -Wall -DWIN32 \
-I/c/progs/devlibs32/include -I/c/progs/devlibs32/include/freetype2\
-o ft_example ft_example.c\
-lfreetype6 -lfontconfig-1 -L/c/progs/devlibs32/bin
On Linux use:
gcc -Wall -I/usr/include/freetype2 -o ft_example ft_example.c -lfreetype -lfontconfig
*/
int main(void){
FT_Library library;
FT_Face face;
FT_Glyph glyph;
int error,glyph_index;
char string[]="Hello World";
char *ptr;
FcPattern *pattern, *fpat;
FcResult result = FcResultMatch;
FcChar8 *filename;
int font_index;
double font_size;
FcMatrix *font_matrix = NULL;
if(!FcInit()) {
printf("FcInit failed\n");
exit(EXIT_FAILURE);
}
if((pattern = FcNameParse((const FcChar8 *)"Arial")) == NULL) {
printf("FcNameParse failed\n");
exit(EXIT_FAILURE);
}
if(!FcConfigSubstitute(NULL, pattern, FcMatchPattern)) {
printf("FcConfigSubstitute failed\n");
exit(EXIT_FAILURE);
}
FcDefaultSubstitute(pattern);
if((fpat = FcFontMatch(NULL, pattern, &result)) == NULL ||
result != FcResultMatch) {
printf("FcFontMatch failed\n");
exit(EXIT_FAILURE);
}
if(FcPatternGetString(fpat, FC_FILE, 0, &filename) != FcResultMatch) {
printf("FcPatternGetString failed\n");
exit(EXIT_FAILURE);
}
if(FcPatternGetInteger(fpat, FC_INDEX, 0, &font_index) != FcResultMatch) {
printf("FcPatternGetInteger failed\n");
exit(EXIT_FAILURE);
}
if(FcPatternGetDouble(fpat, FC_SIZE, 0, &font_size) != FcResultMatch) {
printf("FcPatternGetDouble failed\n");
exit(EXIT_FAILURE);
}
if(FcPatternGetMatrix(fpat, FC_MATRIX, 0, &font_matrix) != FcResultMatch) {
font_matrix = NULL;
}
printf("Using filename:%s\n",filename);
error = FT_Init_FreeType( &library);
if(error){
printf("Oops, could not init freetype, error:%d\n",error);
exit(EXIT_FAILURE);
}
// error = FT_New_Face( library, ARIALFILE, 0, &face );
error = FT_New_Face( library, (const char *) filename, 0, &face );
if(error){
printf("Oops, could not open file, error:%d\n",error);
exit(EXIT_FAILURE);
}
error = FT_Set_Char_Size(
face, /* handle to face object */
0, /* char_width in 1/64th of points */
16*64, /* char_height in 1/64th of points */
300, /* horizontal device resolution */
300 ); /* vertical device resolution */
for(ptr=&string[0]; *ptr; ptr++){
glyph_index = FT_Get_Char_Index( face, *ptr );
error = FT_Load_Glyph( face, glyph_index, FT_LOAD_TARGET_NORMAL );
if (!error){
error = FT_Get_Glyph( face->glyph, &glyph );
if ( !error ) {
printf("letter:%c advance = %ld\n",*ptr, face->glyph->advance.x);
FT_Done_Glyph(glyph);
}
else {
printf("Oops, could not FT_Get_Glyph\n");
}
}
else {
printf("Oops, could not FT_Load_Glyph\n");
}
}
FT_Done_Face( face ); /* release memory for face*/
FT_Done_FreeType(library); /* release all FreeType memory */
FcFini(); /* shut down FontConfig, release memory */
exit(EXIT_SUCCESS);
}
_______________________________________________
Fontconfig mailing list
Fontconfig@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/fontconfig