Re: Memory leak with image surfaces

Victor Goya <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <CAAMrLswStFx6jba3U0Pg+KL_MsUrV+yYrAzmCG4Qfh=bign=zw@mail.gmail.com>
Git bisect points to this commit:

commit 0bfd2acd35547fc2bd0de99cc67d153f0170697d
Author: Chris Wilson <[email protected]>
Date:   Mon Aug 13 01:34:12 2012 +0100

    xlib: Implement SHM fallbacks and fast upload paths

This commit is rather big, I can't figure out what is wrong with it yet.

-- 
Victor Goya

On Fri, Jun 14, 2013 at 8:15 PM, Victor Goya <[email protected]> wrote:
> Hello!
>
> The following test produces a memory leak in the read_png() method:
>
> #include <cairo/cairo.h>
> #include <stdlib.h>
>
> int main() {
>     int              w, h;
>     cairo_surface_t *image;
>     cairo_surface_t *pdf;
>     cairo_t *        cr;
>     int i;
>
>     pdf = cairo_pdf_surface_create("/tmp/lol.pdf", 1500, 1500);
>     cr = cairo_create(pdf);
>
>     image = cairo_image_surface_create_from_png ("./test.png");
>     w = cairo_image_surface_get_width (image);
>     h = cairo_image_surface_get_height (image);
>
>     cairo_scale (cr, 256.0/w, 256.0/h);
>
>     cairo_set_source_surface (cr, image, 0, 0);
>     cairo_paint (cr);
>     cairo_surface_destroy (image);
>
>     cairo_show_page(cr);
>
>     cairo_surface_destroy(pdf);
>     cairo_destroy (cr);
> }
>
> Valgrind output :
>
> ==29797== HEAP SUMMARY:
> ==29797==     in use at exit: 172,738 bytes in 13 blocks
> ==29797==   total heap usage: 84 allocs, 71 frees, 997,686 bytes allocated
> ==29797==
> ==29797== 160,000 bytes in 1 blocks are definitely lost in loss record 13 of 13
> ==29797==    at 0x4C28BED: malloc (in
> /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==29797==    by 0x4EDC7D1: read_png (cairo-png.c:661)
> ==29797==    by 0x4EDD1ED: cairo_image_surface_create_from_png (cairo-png.c:779)
> ==29797==    by 0x400AAC: main (test.c:14)
> ==29797==
> ==29797== LEAK SUMMARY:
> ==29797==    definitely lost: 160,000 bytes in 1 blocks
> ==29797==    indirectly lost: 0 bytes in 0 blocks
> ==29797==      possibly lost: 0 bytes in 0 blocks
> ==29797==    still reachable: 12,738 bytes in 12 blocks
> ==29797==         suppressed: 0 bytes in 0 blocks
>
> I ran into the same problem with larger PDF files, the decompressed
> images are never freed.
>
> The issue seems to be related to the "COW snapshots" feature :
> "_cairo_image_surface_snapshot" create a clone of the surface but set
> the "owns_data" flag of both the surface and its clone to FALSE. This
> can lead in a situation where neither the original surface nor its
> clone own the data, this results in a memory leak because none of them
> take the responsability to free it.
>
> My guess is that the clone should copy the "owns_data" flag of the
> original surface before setting the "owns_data" flag of the original
> surface to FALSE. This way the clone is responsible to free the data
> only if the original surface owned it. I'm not quite sure about all
> the implications of the attached patch, but it fixes the leak for my
> use case.
>
> --- a/src/cairo-image-surface.c
> +++ b/src/cairo-image-surface.c
> @@ -762,12 +762,13 @@ _cairo_image_surface_snapshot (void *abstract_surface)
>      return &clone->base;
>
>   image->pixman_image = NULL;
> +
> + clone->owns_data = image->owns_data;
>   image->owns_data = FALSE;
>
>   clone->transparency = image->transparency;
>   clone->color = image->color;
>
> - clone->owns_data = FALSE;
>   return &clone->base;
> }
>
> Thanks!
>
> --
> Victor Goya
-- 
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.