GNOME Bugzilla – Bug 362181
Cairo::RefPtr leaking memory
Last modified: 2006-12-08 08:31:34 UTC
I was running some valgrind tests on my app that uses gtkmm and cairomm, and noticed that whenever I did the following: Glib::RefPtr<Gdk::Window> win = get_window(); Cairo::RefPtr<Cairo::Context> cr = win->create_cairo_context(); valgrind reported that memory was 'definitely' lost. I read on the cairomm list at http://lists.freedesktop.org/archives/cairo/2006-June/007112.html that this is due to a buggy implementation of Cairo::RefPtr. I was told that this had been resolved and I should post a test case here. My cairomm version is cairomm-1.2.0 My gtkmm version is gtkmm24-2.10.2
Please attach an actual compileable test case.
Please?
Ah, sorry, I totally forgot about this. I'll put one up when I get back to work monday at the latest.
Created attachment 77091 [details] Compilable test case compile with: g++ -o cairo-test `pkg-config --libs --cflags gtkmm-2.4` `pkg-config --libs --cflags cairomm-1.0` main.cc
So here it is. Happy Thanksgiving! A run of valgrind for 30 seconds or so gives this 'definitely lost' report: ==16024== 204,048 (12,816 direct, 191,232 indirect) bytes in 267 blocks are definitely lost in loss record 121 of 123 ==16024== at 0x40053C0: malloc (vg_replace_malloc.c:149) ==16024== by 0x4066AC8: cairo_create (in /usr/lib/libcairo.so.2.10.0) ==16024== by 0x4B2513: gdk_cairo_create (in /usr/lib/libgdk-x11-2.0.so.0.1000.6) ==16024== by 0xA5494D: Gdk::Drawable::create_cairo_context() (in /usr/lib/libgdkmm-2.4.so.1.0.30) ==16024== by 0x804CA47: CairoTest::on_expose_event(_GdkEventExpose*) (main.cc:28) ==16024== by 0x2257942: Gtk::Widget_Class::expose_event_callback(_GtkWidget*, _GdkEventExpose*) (in /usr/lib/libgtkmm-2.4.so.1.0.30) ==16024== by 0x7130FF: (within /usr/lib/libgtk-x11-2.0.so.0.1000.6) ==16024== by 0x2F8578: (within /lib/libgobject-2.0.so.0.1200.4) ==16024== by 0x2F9D8A: g_closure_invoke (in /lib/libgobject-2.0.so.0.1200.4) ==16024== by 0x30B352: (within /lib/libgobject-2.0.so.0.1200.4) ==16024== by 0x30BFC6: g_signal_emit_valist (in /lib/libgobject-2.0.so.0.1200.4) ==16024== by 0x30C3B8: g_signal_emit (in /lib/libgobject-2.0.so.0.1200.4)
Created attachment 77092 [details] valgrind output snippet Bah, it mangled the last one...
Attempting to paste my valgrind --leak-check=full output: 0== 23,040 (1,440 direct, 21,600 indirect) bytes in 30 blocks are definitely lost in loss record 108 of 113 ==29050== at 0x4021396: malloc (vg_replace_malloc.c:149) ==29050== by 0x4898569: cairo_create (cairo.c:188) ==29050== by 0x47ADF2B: gdk_cairo_create (gdkcairo.c:46) ==29050== by 0x434C16D: Gdk::Drawable::create_cairo_context() (drawable.cc:370) ==29050== by 0x804CA5B: CairoTest::on_expose_event(_GdkEventExpose*) (in /home/murrayc/a.out) ==29050== by 0x4248ED2: Gtk::Widget_Class::expose_event_callback(_GtkWidget*, _GdkEventExpose*) (widget.cc:4401) ==29050== by 0x44E9557: _gtk_marshal_BOOLEAN__BOXED (gtkmarshalers.c:83) ==29050== by 0x48F88CE: g_type_class_meta_marshal (gclosure.c:567) ==29050== by 0x48F8EFE: g_closure_invoke (gclosure.c:490) ==29050== by 0x490972D: signal_emit_unlocked_R (gsignal.c:2476) ==29050== by 0x490A853: g_signal_emit_valist (gsignal.c:2207) ==29050== by 0x490AE48: g_signal_emit (gsignal.c:2241) ==29050== by 0x460CCD8: gtk_widget_event_internal (gtkwidget.c:3911) ==29050== by 0x44E7CB2: gtk_main_do_event (gtkmain.c:1380) ==29050== by 0x47C82E7: gdk_window_process_updates_internal (gdkwindow.c:2324) ==29050== by 0x47C83BA: gdk_window_process_all_updates (gdkwindow.c:2387) ==29050== by 0x47C843B: gdk_window_update_idle (gdkwindow.c:2245) ==29050== by 0x49771E6: g_idle_dispatch (gmain.c:4073) ==29050== by 0x4974CAC: g_main_context_dispatch (gmain.c:2049) ==29050== by 0x4977F85: g_main_context_iterate (gmain.c:2681)
So, possibly we are deleting the C++ instance but not unrefing the C instance.
This has been my workaround that seems to fix it... in the expose function, cairo_t* crc = do_cairo_create(); Cairo::Context* cr = new Cairo::Context(crc, true); draw(cr); delete cr;
Created attachment 77301 [details] [review] cairo_refs.patch I found that and 2 other places where we do excess references, in different ways. This patch should fix that, though I'd like you to test it a bit before I commit it. I feel like I've done this before, though maybe it was something else.
I haven't looked at this at all yet. Are you saying that there are no problems in Cairo::RefPtr itself, just in gtkmm functions that use cairo them?
Yes, Jonner, I don't think there are any problems in cairomm.
I'm going to assume that this is correct. It's been sitting in CVS for a while and I will now do a tarball release. Thanks all.