Bug 222951 - gdk_pixbuf_loader_write() failure leaks memory
gdk_pixbuf_loader_write() failure leaks memory
Product: Fedora
Classification: Fedora
Component: gtk+ (Show other bugs)
All Linux
medium Severity medium
: ---
: ---
Assigned To: Matthias Clasen
David Lawrence
Depends On:
  Show dependency treegraph
Reported: 2007-01-16 18:21 EST by David Nečas
Modified: 2007-11-30 17:11 EST (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2007-02-25 11:14:11 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)
test program C source (1.55 KB, text/plain)
2007-01-16 18:21 EST, David Nečas
no flags Details

  None (edit)
Description David Nečas 2007-01-16 18:21:16 EST
Description of problem:
GdkPixbufLoaders are closed when an error in gdk_pixbuf_loader_write() occurs.
And they leak memory when they do.

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1. Consider the attached program that gets the list of pixbuf loaders,
instantiates them, writes some junk data to make them fail and then tries to
clean up.

2. Compile it
gcc -Wall -W -DOLD_STYLE_FINALIZATION $(pkg-config --cflags --libs
gdk-pixbuf-2.0) -o pixbuf-ctx-leak pixbuf-ctx-leak.c
and run
valgrind ./pixbuf-ctx-leak

3. Compile it
gcc -Wall -W $(pkg-config --cflags --libs gdk-pixbuf-2.0) -o pixbuf-ctx-leak
and run
valgrind ./pixbuf-ctx-leak

Actual results:
In both cases 2 and 3:
==6619== Memcheck, a memory error detector.
==6619== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==6619== Using LibVEX rev 1658, a library for dynamic binary translation.
==6619== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==6619== Using valgrind-3.2.1, a dynamic binary instrumentation framework.
==6619== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==6619== For more details, rerun with: -v
wbmp: gdk_pixbuf_loader_write() unexpectedly succeeded.
wmf: gdk_pixbuf_loader_write() unexpectedly succeeded.
ERROR: meta.c (179): wmf_header_read: this isn't a wmf file
jpeg: gdk_pixbuf_loader_write() failed (as expected): Error interpreting JPEG
image file (Not a JPEG file: starts with 0x44 0x6f)
ani: gdk_pixbuf_loader_write() failed (as expected): Invalid header in animation
bmp: gdk_pixbuf_loader_write() failed (as expected): Not enough memory to load
bitmap image
gif: gdk_pixbuf_loader_write() failed (as expected): File does not appear to be
a GIF file
ico: gdk_pixbuf_loader_write() unexpectedly succeeded.
pcx: gdk_pixbuf_loader_write() failed (as expected): Image has invalid width
and/or height
png: gdk_pixbuf_loader_write() failed (as expected): Fatal error reading PNG
image file: Not a PNG file
pnm: gdk_pixbuf_loader_write() failed (as expected): PNM file has an incorrect
initial byte
ras: gdk_pixbuf_loader_write() failed (as expected): RAS image has bogus header data
tga: gdk_pixbuf_loader_write() failed (as expected): TGA image type not supported
xbm: gdk_pixbuf_loader_write() unexpectedly succeeded.
tiff: gdk_pixbuf_loader_write() unexpectedly succeeded.
xpm: gdk_pixbuf_loader_write() unexpectedly succeeded.
svg: gdk_pixbuf_loader_write() failed (as expected): Error writing
==6619== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 1)
==6619== malloc/free: in use at exit: 327,835 bytes in 1,018 blocks.
==6619== malloc/free: 2,532 allocs, 1,514 frees, 1,636,349,655 bytes allocated.
==6619== For counts of detected errors, rerun with: -v
==6619== searching for pointers to 1,018 not-freed blocks.
==6619== checked 1,208,528 bytes.
==6619== LEAK SUMMARY:
==6619==    definitely lost: 166,739 bytes in 27 blocks.
==6619==      possibly lost: 5,648 bytes in 23 blocks.
==6619==    still reachable: 155,448 bytes in 968 blocks.
==6619==         suppressed: 0 bytes in 0 blocks.
==6619== Use --leak-check=full to see details of leaked memory.

Expected results:
Much less definitely lost memory in LEAK SUMMARY.  There is a small constant
amount (48 bytes on x86_64) that valgrind reports as lost due to an GObject
initialization trickery, but the rest seems to be a real leak.

Additional info:
Case 3 is clean up according to the documentation, case 2 is the traditional
clean up (see bug 220562).  They work identically now, they are listed both to
check they work identically also after the eventual fix.

Run valgrind with --leach-check=full to see all the strack traces, however the
individual leaks are similar and look like (FOO is the loader type):
==7651== 4,216 bytes in 1 block are definitely lost in loss record 158 of 177
==7651==    at 0x4A05879: malloc (vg_replace_malloc.c:149)
==7651==    by 0x6048E4A: gdk_pixbuf__FOO_image_begin_load (io-FOO.c:816)
==7651==    by 0x3956A091A3: gdk_pixbuf_loader_load_module (gdk-pixbuf-loader.c:374)
==7651==    by 0x3956A098C0: gdk_pixbuf_loader_new_with_type
==7651==    by 0x400A14: main (pixbuf-ctx-leak.c:28)

The amount of memory lost increases linearly with the number of repetions of the
whole procedure (if one tries it) which indicates the leaks are real.

When the loaders are closed immediately, they do not leak memory (well, except
svg which seems to leak something and wmf which crashes, but they do not belong
to gtk2 package).

The test program is not capable of making all loaders to fail, some perhaps do
not support partial image loading and thus gdk_pixbuf_loader_write() never fails.

I would report it to GNOME bugzilla, but I'm confused which upstream version the
Fedora pixbuf loader code matches, if any...
Comment 1 David Nečas 2007-01-16 18:21:17 EST
Created attachment 145755 [details]
test program C source
Comment 2 Matthias Clasen 2007-01-16 23:57:02 EST
Thanks for that testcase. I think the right fix is to just call
gdk_pixbuf_loader_close instead of duplicating part of that function in the
error case in gdk_pixbuf_loader_write
Comment 3 Matthias Clasen 2007-02-25 11:14:11 EST
This has been fixed in the meantime.

Note You need to log in before you can comment on or make changes to this bug.