GNOME Bugzilla – Bug 736825
Significant memory leak when rsvg_handle_new_from_file fails
Last modified: 2015-04-26 18:06:17 UTC
When using a theme in png format (e.g. 'smooth') some memory (about 5 MB) leaks with every click on a tile. Tested with version 3.10.2 on X/K/Ubuntu 14.04 and with version 3.12.2 on Debian testing. To reproduce the problem, start gnome-mahjongg and change the theme to 'smooth'. Then just click on some tiles and watch the memory grow. I had some trouble building from source (advise would be appreciated; builds and starts fine, but doesn't find themes, maps...) but I looked around using valgrind and found this: ==4408== 112,749,440 bytes in 215 blocks are possibly lost in loss record 8,478 of 8,478 ==4408== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==4408== by 0x507A762: xmlBufResize (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1) ==4408== by 0x507A916: xmlBufAdd (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1) ==4408== by 0x502C8B6: xmlParserInputBufferPush (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1) ==4408== by 0x501882E: xmlParseChunk (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1) ==4408== by 0x467C574: rsvg_handle_write (in /usr/lib/i386-linux-gnu/librsvg-2.so.2.40.2) ==4408== by 0x4660E4B: ??? (in /usr/lib/i386-linux-gnu/librsvg-2.so.2.40.2) ==4408== by 0x4660F66: rsvg_handle_new_from_file (in /usr/lib/i386-linux-gnu/librsvg-2.so.2.40.2) ==4408== by 0x804F68A: ??? (in /usr/games/gnome-mahjongg) ==4408== by 0x804FA5C: ??? (in /usr/games/gnome-mahjongg) ==4408== by 0x80502D1: ??? (in /usr/games/gnome-mahjongg) ==4408== by 0x420A835: ??? (in /usr/lib/i386-linux-gnu/libgtk-3.so.0.1000.8) ==4408== by 0x49615A3: ??? (in /usr/lib/i386-linux-gnu/libgobject-2.0.so.0.4000.0) ==4408== by 0x4962A7D: g_closure_invoke (in /usr/lib/i386-linux-gnu/libgobject-2.0.so.0.4000.0) ==4408== by 0x4974C7F: ??? (in /usr/lib/i386-linux-gnu/libgobject-2.0.so.0.4000.0) ==4408== by 0x497C68E: g_signal_emit_valist (in /usr/lib/i386-linux-gnu/libgobject-2.0.so.0.4000.0) ==4408== by 0x497CBF2: g_signal_emit (in /usr/lib/i386-linux-gnu/libgobject-2.0.so.0.4000.0) ==4408== by 0x4352B0A: ??? (in /usr/lib/i386-linux-gnu/libgtk-3.so.0.1000.8) ==4408== by 0x4208744: ??? (in /usr/lib/i386-linux-gnu/libgtk-3.so.0.1000.8) ==4408== by 0x420A4C1: gtk_main_do_event (in /usr/lib/i386-linux-gnu/libgtk-3.so.0.1000.8) My guess is, that in function get_theme_dimensions() librsvg is leaking memory, trying to parse the png file.
Oh wow, that's pretty bad... good thing this doesn't affect the default postmodern theme.
(In reply to comment #0) > My guess is, that in function get_theme_dimensions() librsvg is leaking memory, > trying to parse the png file. Your guess is correct, though I should add that it's also leaking in load_theme() as well, and we just don't notice because that only runs once. librsvg leaks when loading the PNG fails. The relevant code in Mahjongg looks like this: try { var svg = new Rsvg.Handle.from_file (theme); // Expected to fail if file is a PNG. // ... } catch (Error e) { // Load file as pixbuf instead } Removing the try block (safe if you first set your theme to smooth) fixes the bug.
I think this is the problem spot: ==14497== 6,913,075 (9,776 direct, 6,903,299 indirect) bytes in 13 blocks are definitely lost in loss record 9,206 of 9,206 ==14497== at 0x4C2745D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==14497== by 0x8B94B9E: xmlNewParserCtxt (parserInternals.c:1828) ==14497== by 0x8BA7424: xmlCreatePushParserCtxt (parser.c:12384) ==14497== by 0x4198F88: rsvg_handle_write_impl (rsvg-base.c:1133) ==14497== by 0x419A135: rsvg_handle_write (rsvg-base.c:1703) ==14497== by 0x417A28F: rsvg_handle_fill_with_data (rsvg-base-file-util.c:39) ==14497== by 0x417A3D4: rsvg_handle_new_from_file (rsvg-base-file-util.c:101) ==14497== by 0x40DCEF: game_view_get_theme_dimensions (game-view.vala:211) ==14497== by 0x40D7AA: game_view_update_dimensions (game-view.vala:180) ==14497== by 0x40BCBC: game_view_draw_game (game-view.vala:64) ==14497== by 0x40E472: game_view_real_draw (game-view.vala:270) ==14497== by 0x503989D: _gtk_marshal_BOOLEAN__BOXEDv (gtkmarshalers.c:130) ==14497== by 0x5171E9C: gtk_widget_draw_marshallerv (gtkwidget.c:1096) ==14497== by 0x59BA09E: _g_closure_invoke_va (gclosure.c:831) ==14497== by 0x59D30EB: g_signal_emit_valist (gsignal.c:3218) ==14497== by 0x59D3D71: g_signal_emit (gsignal.c:3365) ==14497== by 0x5180CC9: _gtk_widget_draw_internal.part.64 (gtkwidget.c:6951) ==14497== by 0x518238E: _gtk_widget_draw_windows (gtkwidget.c:6931) ==14497== by 0x51825DE: _gtk_widget_draw (gtkwidget.c:7122) ==14497== by 0x4F848F4: gtk_container_propagate_draw (gtkcontainer.c:3586) I don't think librsvg is doing anything wrong, so reassigning yet again to libxml2.
This is with libxml2 2.9.1 (it looks like the version list in Bugzilla hasn't been updated in a while).
I copypasted the wrong trace, here's the right one: ==14497== 1,048,832 bytes in 2 blocks are possibly lost in loss record 9,198 of 9,206 ==14497== at 0x4C2745D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==14497== by 0x8C0C17B: xmlBufResize (buf.c:813) ==14497== by 0x8C0C2D4: xmlBufAdd (buf.c:870) ==14497== by 0x8BC08FA: xmlParserInputBufferPush (xmlIO.c:3250) ==14497== by 0x8BACD6E: xmlParseChunk (parser.c:12229) ==14497== by 0x4198FDD: rsvg_handle_write_impl (rsvg-base.c:1143) ==14497== by 0x419A135: rsvg_handle_write (rsvg-base.c:1703) ==14497== by 0x417A28F: rsvg_handle_fill_with_data (rsvg-base-file-util.c:39) ==14497== by 0x417A3D4: rsvg_handle_new_from_file (rsvg-base-file-util.c:101) ==14497== by 0x40DCEF: game_view_get_theme_dimensions (game-view.vala:211)
What is libsvg strategy on parsing error ? Seems they call xmlCreatePushParserCtxt() directly but 'forget' to free it when some of the chunk fails to parse... Daniel
OK, you're right. Thanks for the help!
Created attachment 286505 [details] [review] When loading an image fails, don't leak it Here's a quick patch that fixes the leak in rsvg_handle_fill_with_data, which is what's causing problems for gnome-mahjongg, but there are equivalent leaks in rsvg_defs_load_extern and rsvg_pixbuf_from_data_with_size_data as well, so this should either be fixed in all three places, or else rsvg_handle_write should call rsvg_handle_close when it fails.
Created attachment 286523 [details] [review] handle: Call close() after write() even on write error Otherwise the internal xmlDoc will leak.
Comment on attachment 286505 [details] [review] When loading an image fails, don't leak it Your patch looks good to me.
Christian, is your patch ready to be pushed?
Pushed to master; please test.
*** Bug 748460 has been marked as a duplicate of this bug. ***