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): gtk2-2.10.4-10.fc6 How reproducible: Always. 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 pixbuf-ctx-leak.c 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 ==6619== 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== ==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== ==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 (gdk-pixbuf-loader.c:533) ==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...
Created attachment 145755 [details] test program C source
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
This has been fixed in the meantime.