[Fontconfig] FontConfig memory question

mathog mathog at caltech.edu
Fri Feb 14 01:54:19 CET 2014


On 12-Feb-2014 18:39, Akira TAGOH wrote:
> Apparently you are missing calling FcFontSetDestroy() for fontset and
> FcPatternDestroy() for fpat though, is it done at the out of snippets
> right?

Right. Those are destroyed when all of the text has been processed.

> 
> Another question is, what pattern are you giving to fontspec? is it
> possible to reproduce that issue with fc-match -s perhaps?

The value of fsp->fontspec seen in the debugger is: "Ezra SIL 
SR:slant=0:weight=80:size=7.200000:width=100"

I just reran this valgrind analysis using a a file with a single input 
text string, so it only passed through the snippet one time.  As before 
it leaked at the first line in the snippet, even though the pattern 
created is clearly destroyed after the while(), and it also leaked at 
the line where the fpat was created. (Line 757, marked now in the 
snippet, now following my signature.) The "fontset" did not leak. It did 
this even though in both cases I watched it in the debugger pass 
execution to the appropriate destroy function.  For 750 to 
FcPatternDestroy(pattern) in the snippet, and for 756 to

           FcPatternDestroy(fsp->fpat);    /* release memory for 
FontConfig fpats            */

in another routine.  The pointers created in the snippet were at 
0xb911b20 and 0xb911b08, respectively, and those variables had the same 
pointers at the time they called the destroy
routines.

It seems like something is going on "inside" FontConfig to leave the 
memory behind.  The REALLY weird part is that when this same pattern is 
run in text_reassemble, the standalone test version of the libTERE code, 
when processing the same input, valgrind sees no leak.  That is 
particularly mind boggling for the "pattern" leak, because that happens 
entirely within this routine.  Apparently something Inkscape did to 
FontConfig at some earlier time "enables" the leak at this point.  At 
least that is one hypothesis.

Is there some way to see what is "inside" pattern and fpat?  They are 
incomplete types, so gdb won't tell me anything more than the pointer 
address.

Thanks,

David Mathog
mathog at caltech.edu
Manager, Sequence Analysis Facility, Biology Division, Caltech
> 
> On Thu, Feb 13, 2014 at 7:39 AM, mathog <mathog at caltech.edu> wrote:
>> He all,
>> 
>> The question concerns the bit of FontConfig using code below (sorry 
>> about
>> the wrap) which is leaking memory in some mysterious manner, but so 
>> far only
>> when compiled into Inkscape, and only, apparently, for certain fonts.  
>> (The
>> one case where I see this is a test sample containing Hebrew Ezra SIL 
>> and
>> Ezra SIL SR fonts.)  The code is part of the file text_reassemble.c 
>> which is
>> from libTERE (on sourceforge) but it is also included in Inkscape.  I 
>> have
>> traced through this and in every instance "pattern", the pointer to 
>> the
>> leaking memory, was sent to FcPatternDestroy.  Yet when run in 
>> valgrind the
>> line where that pointer is attached to memory shows up as a leak.
>> 
>> Any idea what this might be???  I thought that it might have been a 
>> case
>> where something later on replaces a field in "pattern", but that 
>> should have
>> given the "definitely lost" message in valgrind, not "still 
>> reachable".  The
>> only other thing that comes to mind is that FcNameParse itself leaks 
>> memory
>> internally for certain fontspec's, and this has nothing to do with the
>> "pattern" variable in this code.  This is on a Ubuntu 12.04.04 system, 
>> with
>> fontconfig 2.8.0-3ubuntu9.1 packages.
>> 
>> Here is the code snippet:
>> 
>>    pattern = FcNameParse((const FcChar8 *)fontspec);  //<--- line 750,
>> problem is here
>>    while(1) {  /* this is NOT a loop, it uses breaks to avoid gotos 
>> and deep
>> nesting */
>>    if(!(pattern)){
>> status = -2;   break; }
>>       if(!FcConfigSubstitute(NULL, pattern, FcMatchPattern)){
>> status = -3;   break; };
>>       FcDefaultSubstitute(pattern);
>>       /*  get a fontset, trimmed to only those with new glyphs as 
>> needed, so
>> that missing glyph's may be handled */
>>       if(!(fontset = FcFontSort (NULL,pattern, FcTrue, NULL, &result)) 
>> ||
>> (result != FcResultMatch)){ status = -4;   break; }
>>       if(!(fpat = FcFontRenderPrepare(NULL, pattern, 
>> fontset->fonts[0]))){
>> status = -405; break; } // <-- second leak, line 757
>>       if(FcPatternGetString(  fpat, FC_FILE,   0, (FcChar8 
>> **)&filename)  !=
>> FcResultMatch){          status = -5;   break; }
>>       if(FcPatternGetDouble(  fpat, FC_SIZE,   0,  &fd)                
>>    !=
>> FcResultMatch){          status = -6;   break; }
>> 
>>       /* copy these into memory for external use */
>>       fsp                   = &(fti->fonts[fti->used]);
>>       fsp->fontset          = fontset;
>>       fsp->alts             = NULL;  /* Initially no links to 
>> alternate
>> fonts */
>>       fsp->space            = 0;
>>       fsp->file             = (uint8_t *) U_strdup((char *) filename);
>>       fsp->fontspec            = (uint8_t *) U_strdup((char *) 
>> fontspec);
>>       fsp->fpat             = fpat;
>>       fsp->fsize            = fd;
>>       break;
>>    }
>>    /* release FC's own memory related to this call that does not need 
>> to be
>> kept around so that face will work */
>>    if(pattern)FcPatternDestroy(pattern); /* done with this memory */
>> 
>> and here is the valgrind log:
>> 
>> 45 bytes in 2 blocks are still reachable in loss record 26,064 of 
>> 38,661
>>    at 0x402BE68: malloc (in
>> /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
>>    by 0x4FAFD42: ??? (in 
>> /usr/lib/i386-linux-gnu/libfontconfig.so.1.4.4)
>>    by 0x4FB0914: ??? (in 
>> /usr/lib/i386-linux-gnu/libfontconfig.so.1.4.4)
>>    by 0x4FADF4B: FcNameParse (in
>> /usr/lib/i386-linux-gnu/libfontconfig.so.1.4.4)
>>    by 0x83868EF: ftinfo_load_fontname (text_reassemble.c:750)
>>    by 0x83A4F57:
>> Inkscape::Extension::Internal::Emf::myEnhMetaFileProc(char*, unsigned 
>> int,
>> Inkscape::Extension::Internal::EMF_CALLBACK_DATA*) 
>> (emf-inout.cpp:3047)
>>    by 0x83A782D:
>> Inkscape::Extension::Internal::Emf::open(Inkscape::Extension::Input*, 
>> char
>> const*) (emf-inout.cpp:3429)
>>    by 0x8322F09: Inkscape::Extension::Input::open(char const*)
>> (input.cpp:153)
>>    by 0x8320A99: 
>> Inkscape::Extension::open(Inkscape::Extension::Extension*,
>> char const*) (system.cpp:117)
>>    by 0x80F58FC: sp_file_open(Glib::ustring const&,
>> Inkscape::Extension::Extension*, bool, bool) (file.cpp:274)
>>    by 0x8087762: sp_main_gui(int, char const**) (main.cpp:1065)
>> 
>> Thank you,
>> 
>> David Mathog
>> mathog at caltech.edu
>> Manager, Sequence Analysis Facility, Biology Division, Caltech
>> 
>> _______________________________________________
>> Fontconfig mailing list
>> Fontconfig at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/fontconfig



More information about the Fontconfig mailing list