GNOME Bugzilla – Bug 738868
Memory leak under Windows 7 if gtk_widget_modify_font used
Last modified: 2015-03-24 18:45:00 UTC
Created attachment 288941 [details] source code of application what reproduce mem leak under Windows 7 During searching for memory leak in my application i discovered that leak happens only under Windows 7 X64 (no Window XP 64 bit, nor Linux x64). Leak appear if label widget been has modified font with gtk_widget_modify_font. I created minimal test application that demonstrate leak. Each text update on label cause a mem usage grow. Mem grow become faster if affinity changed on executable process to one CPU. Removing gtk_widget_modify_font from code fix situation. gtk+-2.24.24 and pango-1.36.8 is used.
i did some tests with umdh and found that mem leak happens in pango. here is a diff of umdh output: + 78a9f70 ( 7d12060 - 4680f0) 1 allocs BackTrace4CFF760 + 0 ( 1 - 1) BackTrace4CFF760 allocations ntdll!RtlWow64EnableFsRedirection+0000E588 msvcrt!realloc+00000052 libglib-2.0-0!g_realloc+00000036 libgobject-2.0-0!g_object_weak_ref+0000007E libpangocairo-1.0-0!pango_cairo_error_underline_path+00000583 libpangowin32-1.0-0!pango_win32_font_cache_unload+0000143F libpangowin32-1.0-0!pango_win32_font_cache_unload+0000153A libpango-1.0-0!pango_color_parse+00000F21 libpango-1.0-0!pango_itemize_with_base_dir+00000108 libpango-1.0-0!pango_layout_line_get_extents+000006E9 libpango-1.0-0!pango_layout_move_cursor_visually+0000068D libgtk-win32-2.0-0!gtk_label_get_angle+00001C38 libgobject-2.0-0!g_cclosure_marshal_VOID__BOXEDv+0000004C libgobject-2.0-0!g_closure_invoke+000002D0 libgobject-2.0-0!g_signal_emit_valist+00000715 libgobject-2.0-0!g_signal_emit_by_name+0000045F libgtk-win32-2.0-0!gtk_size_group_get_widgets+00000118 libgtk-win32-2.0-0!gtk_box_get_type+00000823 libgobject-2.0-0!g_cclosure_marshal_VOID__BOXEDv+0000004C libgobject-2.0-0!g_closure_invoke+000002D0 libgobject-2.0-0!g_signal_emit_valist+00000715 libgobject-2.0-0!g_signal_emit_by_name+0000045F libgtk-win32-2.0-0!gtk_size_group_get_widgets+00000118 libgtk-win32-2.0-0!gtk_decorated_window_move_resize_window+000015BE libgobject-2.0-0!g_cclosure_marshal_VOID__BOXEDv+0000004C libgobject-2.0-0!g_closure_invoke+0000038D libgobject-2.0-0!g_signal_emit_valist+00000715 libgobject-2.0-0!g_signal_emit_by_name+0000045F libgtk-win32-2.0-0!gtk_size_group_get_widgets+00000118 libgtk-win32-2.0-0!gtk_decorated_window_move_resize_window+00001EA9 libgtk-win32-2.0-0!gtk_decorated_window_move_resize_window+00002575 libgobject-2.0-0!g_closure_invoke+0000038D and it grows. line that cause a leak in pangocairo-win32font.c seems is: [...] g_object_add_weak_pointer (G_OBJECT (win32font->fontmap), (gpointer *) (gpointer) &win32font->fontmap); [...] rather then gdb calc: [...] (gdb) break *(pango_cairo_error_underline_path+0x00000583) Breakpoint 1 at 0x6d4c5ad3: file ../../pango/pangocairo-win32font.c, line 259. (gdb) [...] which is [...] face->cached_fonts = g_slist_prepend (face->cached_fonts, win32font); [...] i did some gdb backtrace and it looks like: (gdb)
+ Trace 234238
it seems that creating some labels with different font cause running *itemize_state_update_for_new_run* each time then labels need to be redrawed, moreover it seems that USE_FACE_CACHED_FONTS code parts not working properly...
i found that problem cased by line in pangocairo-win32font.c [...] g_object_add_weak_pointer (G_OBJECT (win32font->fontmap), (gpointer *) (gpointer) &win32font->fontmap); [...] because of *pango_win32_font_finalize* does not remove that weak leak in pangowin32.c: [...] fontmap = g_weak_ref_get ((GWeakRef *) &win32font->fontmap); if (fontmap) g_object_unref (fontmap); [...] to fix leak it should looks like: [...] fontmap = g_weak_ref_get ((GWeakRef *) &win32font->fontmap); if (fontmap) { g_object_remove_weak_pointer (G_OBJECT (win32font->fontmap), (gpointer *) (gpointer) &win32font->fontmap); g_object_unref (fontmap); } [...] patch will be attached
Created attachment 289102 [details] [review] Fix weak pointer leak This patch fix leak with lost weak references in fontset
i was also trying to resolve why does it happens on Windows 7. i think it happens because of a lot of fonts installed in system that aliased with *Monospace*. it seems asking for font-desc "Monospace 14" will crease a tons of aliases like: courier new lucida console courier monothai mingliu simsun gulimche in the same time fontset's cache is limited: #define MAX_FREED_FONTS 16 that cause cache overflow and further cache miss for next font request, so i suggest to extend MAX_FREED_FONTS value to 256 or 1024 that will make cache size enough for keeping all aliases font there so in my case pango does miss all cache requests because of small cache and long aliases list. so it have to create font each time it need to be redrawed: (gdb) bt
+ Trace 234247
Created attachment 289104 [details] [review] Increase MAX_FREED_FONTS value Increasing MAX_FREED_FONTS value should make fontset's cache working on normal mode because of long aliases list and available fonts under Windows 7
Both patches look good to me. Have not tested.
Attachment 289102 [details] pushed as 92a4e7b - Fix weak pointer leak Attachment 289104 [details] pushed as a533850 - Increase MAX_FREED_FONTS value
*** Bug 745695 has been marked as a duplicate of this bug. ***
Well, I bumped master to 1.37 because you wanted to kill modules and do some other actual development... sadly, it didn't happen. So, I may just cherry-pick a few bug fixes to the 1.36 branch and leave it at that
Umm. Sorry about that. Just put some time aside to do that next week. A maintenance branch might be useful in the mean time. Thanks again.