GNOME Bugzilla – Bug 143542
PangoFT2Fontmap leak
Last modified: 2008-08-22 07:01:44 UTC
An object created with pango_ft2_font_map_new apparently cannot be disposed of properly within the pango API. It appears that the caching system is holding circular pointers somewhere. Calling pango_fc_font_map_cache_clear (which is outside the application API) on the font_map before unref makes things work. (Gnumeric uses pango_ft2_font_map_new for rendering rotated text in a few places. This may become moot when pango supports that.)
*** Bug 138882 has been marked as a duplicate of this bug. ***
I tried to track this down for bug 138882 using the test program attached in that bug. This is what happens when pango_fc_font_map_load_fontset is called: - Each PangoFcFont (or PangoFT2Font in this case) instance that is created by pango_fc_font_map_new_font has a reference to the PangoFcFontMap set in pango_fc_font_map_add - The PangoFontsetSimple instance that is created contains references to the created PangoFcFont instances - pango_fc_font_map_cache_fontset is called which makes the PangoFcFontMap instance have a reference to the PangoFontset instance So there is a circle PangoFcFontMap->PangoFontsetSimple->PangoFcFont->PangoFcFontMap I verified this by removing the ref/unref calls in pango_fc_font_map_cache_fontset, which made the leak in my test program as well as in The GIMP go away at the cost of breaking the fontset cache. Unfortunately I don't know enough about Pango internals to suggest a clean way of fixing this without disabling the fontset cache.
Any hope for this? When we hit this (doing and graphing in gnumeric, for example) we get hundreds of leaks making it totally impossible to find leaks we should worry about.
I'm not expecting to fix this before 1.6.0. It's probably a day of work or so to fix. (Basically, the fix is to change strong references to weak references, but the interaction with caching and performance implications aren't simple.)
*** Bug 164357 has been marked as a duplicate of this bug. ***
For the record, the work-around for this problem is something like this... static void (*fake_pango_fc_font_map_cache_clear) (PangoFcFontMap *); void go_pango_fc_font_map_cache_clear (PangoFcFontMap *font_map) { if (fake_pango_fc_font_map_cache_clear) fake_pango_fc_font_map_cache_clear (font_map); } Init with... GModule *self; if (NULL != (self = g_module_open (NULL, 0))) { gpointer sym; if (g_module_symbol (self, "pango_fc_font_map_cache_clear", &sym)) fake_pango_fc_font_map_cache_clear = sym; g_module_close (self); } ...then call go_pango_fc_font_map_cache_clear before your final unref on it.
For the (perhaps hackish) workaround that was added to GIMP, see bug #148997 and bug #154144. Basically, it calls pango_ft2_font_map_substitute_changed which is public API, and that in turn calls pango_fc_font_map_cache_clear.
Removing keyword; any program that is finalizing FT2 fontmaps has to be considered broken. The ability to finalize FT2 fontmaps is a feature addition, in my opinion.
Owen, you are Yoda debugging: "There is no bug". *Of* *course* it is not a bug releasing the objects you have allocated. That is an absurd thing to say. What you have said previously, namely that programs shouldn't create and destroy fontmaps all the time, makes sense. It would be even better if fontmaps were documented to be heavy-weight. You have also previously said that contexts are cheap, but where is one supposed to know these things from? This bug is impeding memory work in the sense that it creates a lot of noise in leak reports. It's not that finalizing is better at reclaiming memory than _exit.
What I'm saying is that this bug has nothing to do with the overall effort to reduce the memory footprint of GNOME. If a program is affected this bug, it has an *unlimited* leak. Since few people have unlimited memory, my assumption is that the current set of GNOME programs are talking precautions one way or the other to avoid this problem.
*** Bug 344233 has been marked as a duplicate of this bug. ***
*** Bug 351763 has been marked as a duplicate of this bug. ***
*** Bug 394408 has been marked as a duplicate of this bug. ***
*** Bug 528227 has been marked as a duplicate of this bug. ***
2008-08-22 Behdad Esfahbod <behdad@gnome.org> Bug 143542 – PangoFT2Fontmap leak * pango/fonts.c: * pango/pangoatsui.c (pango_atsui_font_finalize), (_pango_atsui_font_set_font_map): * pango/pangocairo-font.c (_pango_cairo_font_get_metrics), (_pango_cairo_font_private_get_hex_box_info): * pango/pangocairo-win32font.c (_pango_cairo_win32_font_new): * pango/pangofc-font.c (pango_fc_font_get_metrics): * pango/pangofc-fontmap.c (pango_fc_font_map_add), (_pango_fc_font_map_remove), (cleanup_font): * pango/pangowin32-fontmap.c (pango_win32_font_neww), (pango_win32_font_map_real_find_font): * pango/pangowin32.c (pango_win32_font_finalize): * pango/pangox-fontmap.c (pango_x_font_map_load_font): * pango/pangox.c (pango_x_font_new), (pango_x_font_finalize): Make the reference the font->fontmap reference weak. The code for setting the reference must look like this: g_assert (font->fontmap == NULL); font->fontmap = (PangoFontMap *) fontmap; g_object_add_weak_pointer (G_OBJECT (font->fontmap), (gpointer *) (gpointer) &font->fontmap); And releasing it like: g_assert (font->fontmap != NULL); g_object_remove_weak_pointer (G_OBJECT (font->fontmap), (gpointer *) (gpointer) &font->fontmap); font->fontmap = NULL; I have converted all fontmaps. The win32 and atsui ones can use some simple testing. The PangoFc fonts actually don't need the weakref as the fontmap already provides a similar link by itself.