GNOME Bugzilla – Bug 775126
memory leak in gdk_wayland_window_ensure_cairo_surface
Last modified: 2017-09-26 19:26:59 UTC
Not sure if this is 3.89 only but I didn't see it in 3.22. I see a fair amount of this when running the current gtk4-widget-factory in valgrind: ==2847== 24,472 (14,592 direct, 9,880 indirect) bytes in 38 blocks are definitely lost in loss record 21,517 of 21,537 ==2847== at 0x4C2AB8D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==2847== by 0x73B05B7: _cairo_image_surface_create_for_pixman_image (cairo-image-surface.c:184) ==2847== by 0x73B0B5E: _cairo_image_surface_create_with_pixman_format (cairo-image-surface.c:353) ==2847== by 0x73B0BFF: cairo_image_surface_create (cairo-image-surface.c:399) ==2847== by 0x4EE9692: gdk_wayland_window_ensure_cairo_surface (gdkwindow-wayland.c:818) ==2847== by 0x4EE9867: gdk_wayland_window_ref_cairo_surface (gdkwindow-wayland.c:858) ==2847== by 0x4ED7E23: gdk_window_ref_impl_surface (gdkwindow.c:2595) ==2847== by 0x4ED7DCF: gdk_window_get_content (gdkwindow.c:2585) ==2847== by 0x4ED82DA: gdk_window_begin_paint_internal (gdkwindow.c:2720) ==2847== by 0x4ED89B9: gdk_window_begin_draw_frame (gdkwindow.c:2908) ==2847== by 0x4FBC268: gtk_widget_render (gtkwidget.c:15744) ==2847== by 0x51AEB57: gtk_main_do_event (gtkmain.c:1787) ==2847== by 0x4F0EE7B: _gdk_event_emit (gdkevents.c:73) ==2847== by 0x4ED9737: _gdk_window_process_updates_recurse_helper (gdkwindow.c:3443) ==2847== by 0x4ED9926: _gdk_window_process_updates_recurse (gdkwindow.c:3495) ==2847== by 0x4EE5DB2: gdk_window_impl_process_updates_recurse (gdkwindowimpl.c:333) ==2847== by 0x4ED9B2C: gdk_window_process_updates_internal (gdkwindow.c:3570) ==2847== by 0x4ED9FF8: gdk_window_process_updates_with_mode (gdkwindow.c:3767) ==2847== by 0x4EE4A05: gdk_window_paint_on_clock (gdkwindow.c:10424) ==2847== by 0xA00DBBF: g_cclosure_marshal_VOID(intXX_t &&) volatile (gmarshal.c:875) ==2847== by 0xA00EA5D: g_closure_invoke (gclosure.c:804) ==2847== by 0x9FEFFC0: signal_emit_unlocked_R.lto_priv.369 (gsignal.c:3635) ==2847== by 0x9FF39E2: g_signal_emit_valist (gsignal.c:3391) ==2847== by 0x9FF3F21: g_signal_emit (gsignal.c:3447) ==2847== by 0x4F133B6: _gdk_frame_clock_emit_paint (gdkframeclock.c:640) ==2847== by 0x4F13F13: gdk_frame_clock_paint_idle (gdkframeclockidle.c:430) ==2847== by 0x4EFF40F: gdk_threads_dispatch (gdk.c:630) ==2847== by 0xA4A3021: g_timeout_dispatch.lto_priv.209 (gmain.c:4674) ==2847== by 0xA4A934D: g_main_dispatch.lto_priv.1021 (gmain.c:3203) ==2847== by 0xA4A201B: g_main_context_dispatch (gmain.c:3856) ==2847== by 0xA4A21FF: g_main_context_iterate (gmain.c:3929) ==2847== by 0xA4A22C3: g_main_context_iteration (gmain.c:3990) ==2847== by 0x9492921: g_application_run (gapplication.c:2381) ==2847== by 0x40670D: main (widget-factory.c:1942)
I don't see that in 3.22 either.
I see it in 3.22.21 in an application that uses OpenGL for an animation. The thing is leaking like a sieve. I investigated a bit, and this code in gdk_wayland_window_ensure_cairo_surface() looks kinda fishy to me: /* If we are drawing using OpenGL then we only need a logical 1x1 surface. */ if (impl->display_server.egl_window) { if (impl->staging_cairo_surface && _gdk_wayland_is_shm_surface (impl->staging_cairo_surface)) cairo_surface_destroy (impl->staging_cairo_surface); impl->staging_cairo_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, impl->scale, impl->scale); cairo_surface_set_device_scale (impl->staging_cairo_surface, impl->scale, impl->scale); } else if (!impl->staging_cairo_surface) Note how cairo_surface_destroy() is only called if _gdk_wayland_is_shm_surface() is TRUE, but the 1x1 dummy surface is recreated in every single drawing call. As I said, the thing really does leak like a sieve. Several megabytes per minute, so it's pretty serious. I suspect that using GL is a precondition for reproducing this with GTK+ 3.22.
Created attachment 360253 [details] [review] Plug the memory leak The attached patch fixes the problem for me. I applied it to my distro GTK+ 3.22 package and the leak is gone. I haven't tested on master but it looks like the code didn't change at all, so it should apply. I can commit it myself if I get the go-ahead.
Pingaling? It would be really nice to get this in, since the leak is really serious when using GTK+ 3.22 on Wayland with GtkGLArea.
Review of attachment 360253 [details] [review]: Looks good to me.
Great. So shall I push to 3.22, master, or both?
Pushed to both branches. Thanks!