After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 736825 - Significant memory leak when rsvg_handle_new_from_file fails
Significant memory leak when rsvg_handle_new_from_file fails
Status: VERIFIED FIXED
Product: librsvg
Classification: Core
Component: general
git master
Other Linux
: Normal major
: ---
Assigned To: librsvg maintainers
librsvg maintainers
: 748460 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2014-09-17 18:30 UTC by zapp
Modified: 2015-04-26 18:06 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
When loading an image fails, don't leak it (965 bytes, patch)
2014-09-18 14:40 UTC, Michael Catanzaro
none Details | Review
handle: Call close() after write() even on write error (2.78 KB, patch)
2014-09-18 16:35 UTC, Christian Persch
none Details | Review

Description zapp 2014-09-17 18:30:32 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.
Comment 1 Michael Catanzaro 2014-09-17 19:59:47 UTC
Oh wow, that's pretty bad... good thing this doesn't affect the default postmodern theme.
Comment 2 Michael Catanzaro 2014-09-17 20:51:34 UTC
(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.
Comment 3 Michael Catanzaro 2014-09-17 23:25:37 UTC
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.
Comment 4 Michael Catanzaro 2014-09-17 23:29:50 UTC
This is with libxml2 2.9.1 (it looks like the version list in Bugzilla hasn't been updated in a while).
Comment 5 Michael Catanzaro 2014-09-17 23:37:27 UTC
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)
Comment 6 Daniel Veillard 2014-09-18 10:08:48 UTC
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
Comment 7 Michael Catanzaro 2014-09-18 14:34:25 UTC
OK, you're right. Thanks for the help!
Comment 8 Michael Catanzaro 2014-09-18 14:40:25 UTC
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.
Comment 9 Christian Persch 2014-09-18 16:35:57 UTC
Created attachment 286523 [details] [review]
handle: Call close() after write() even on write error

Otherwise the internal xmlDoc will leak.
Comment 10 Michael Catanzaro 2014-09-18 21:07:10 UTC
Comment on attachment 286505 [details] [review]
When loading an image fails, don't leak it

Your patch looks good to me.
Comment 11 Michael Catanzaro 2014-09-25 21:38:36 UTC
Christian, is your patch ready to be pushed?
Comment 12 Christian Persch 2014-09-27 20:07:35 UTC
Pushed to master; please test.
Comment 13 Michael Catanzaro 2015-04-26 18:06:17 UTC
*** Bug 748460 has been marked as a duplicate of this bug. ***