From 6167d4d97c39768524c61b09834c16e2a7895970 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 15 Jul 2013 22:01:00 +0100 Subject: [PATCH] Fix three minor memleaks --- README.md | 11 ++++++++++- libvips/arithmetic/linear.c | 4 ++-- libvips/foreign/jpeg2vips.c | 13 +++++++++---- libvips/foreign/jpegsave.c | 2 +- libvips/include/vips/internal.h | 2 ++ libvips/iofuncs/init.c | 2 ++ libvips/iofuncs/type.c | 30 +++++++++++++++++++++++++----- 7 files changed, 51 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index fe6af94d..b60af699 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,8 @@ Checkout the latest sources with: Then for a debug build: $ ./bootstrap.sh - $ CFLAGS="-g -Wall" CXXFLAGS="-g -Wall" ./configure --prefix=/home/john/vips --enable-gtk-doc + $ CFLAGS="-g -Wall" CXXFLAGS="-g -Wall" \ + ./configure --prefix=/home/john/vips --enable-gtk-doc $ make $ make install @@ -41,6 +42,14 @@ Static analysis with: $ cppcheck --force --enable=style . &> cppcheck.log +Leak check: + + $ export G_DEBUG=gc-friendly + $ export G_SLICE=always-malloc + $ valgrind --suppressions=/home/john/nip2.supp \ + --leak-check=yes \ + vips ... > vips-vg.log 2>&1 + # Dependencies libvips has to have gettext, glib-2.x and libxml-2.0. The build system needs diff --git a/libvips/arithmetic/linear.c b/libvips/arithmetic/linear.c index f6548fd0..155cd600 100644 --- a/libvips/arithmetic/linear.c +++ b/libvips/arithmetic/linear.c @@ -135,8 +135,8 @@ vips_linear_build( VipsObject *object ) /* Make up-banded versions of our constants. */ - linear->a_ready = g_new( double, linear->n ); - linear->b_ready = g_new( double, linear->n ); + linear->a_ready = VIPS_ARRAY( linear, linear->n, double ); + linear->b_ready = VIPS_ARRAY( linear, linear->n, double ); for( i = 0; i < linear->n; i++ ) { if( linear->a ) { diff --git a/libvips/foreign/jpeg2vips.c b/libvips/foreign/jpeg2vips.c index 4541f671..777088e2 100644 --- a/libvips/foreign/jpeg2vips.c +++ b/libvips/foreign/jpeg2vips.c @@ -164,9 +164,6 @@ readjpeg_free( ReadJpeg *jpeg ) result = 0; - if( setjmp( jpeg->eman.jmp ) ) - return( -1 ); - if( jpeg->eman.pub.num_warnings != 0 ) { if( jpeg->fail ) { vips_error( "VipsJpeg", "%s", vips_error_buffer() ); @@ -185,13 +182,20 @@ readjpeg_free( ReadJpeg *jpeg ) } if( jpeg->decompressing ) { - jpeg_finish_decompress( &jpeg->cinfo ); + /* jpeg_finish_decompress() can fail ... catch any errors. + */ + if( !setjmp( jpeg->eman.jmp ) ) + jpeg_finish_decompress( &jpeg->cinfo ); + jpeg->decompressing = FALSE; } VIPS_FREEF( fclose, jpeg->eman.fp ); VIPS_FREE( jpeg->filename ); jpeg->eman.fp = NULL; + + /* I don't think this can fail. + */ jpeg_destroy_decompress( &jpeg->cinfo ); return( result ); @@ -210,6 +214,7 @@ readjpeg_new( VipsImage *out, int shrink, gboolean fail ) if( !(jpeg = VIPS_NEW( out, ReadJpeg )) ) return( NULL ); + jpeg->out = out; jpeg->shrink = shrink; jpeg->fail = fail; diff --git a/libvips/foreign/jpegsave.c b/libvips/foreign/jpegsave.c index b2063afe..9ce8b0d5 100644 --- a/libvips/foreign/jpegsave.c +++ b/libvips/foreign/jpegsave.c @@ -237,8 +237,8 @@ vips_foreign_save_jpeg_buffer_build( VipsObject *object ) return( -1 ); area = vips_area_new_blob( (VipsCallbackFn) vips_free, obuf, olen ); - g_object_set( file, "buffer", area, NULL ); + vips_area_unref( area ); return( 0 ); } diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 087eda39..b21c837c 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -90,6 +90,8 @@ extern gboolean vips__cache_trace; void vips__cache_init( void ); +void vips__type_leak( void ); + typedef int (*im__fftproc_fn)( VipsImage *, VipsImage *, VipsImage * ); /* iofuncs diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 9954a224..ebdbd634 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -327,6 +327,8 @@ vips_leak( void ) vips_buf_appends( &buf, "\n" ); fprintf( stderr, "%s", vips_buf_all( &buf ) ); + + vips__type_leak(); } /** diff --git a/libvips/iofuncs/type.c b/libvips/iofuncs/type.c index 59002656..f9bc0f3e 100644 --- a/libvips/iofuncs/type.c +++ b/libvips/iofuncs/type.c @@ -142,7 +142,7 @@ vips_thing_get_type( void ) */ #ifdef DEBUG -static int vips_area_number = 0; +static GSList *vips_area_all = NULL; #endif /*DEBUG*/ VipsArea * @@ -174,6 +174,7 @@ vips_area_unref( VipsArea *area ) #ifdef DEBUG printf( "vips_area_unref: %p count = %d\n", area, area->count ); + g_assert( g_slist_find( vips_area_all, area ) ); #endif /*DEBUG*/ if( area->count == 0 ) { @@ -190,9 +191,9 @@ vips_area_unref( VipsArea *area ) g_free( area ); #ifdef DEBUG - vips_area_number -= 1; + vips_area_all = g_slist_remove( vips_area_all, area ); printf( "vips_area_unref: free .. total = %d\n", - vips_area_number ); + g_slist_length( vips_area_all ) ); #endif /*DEBUG*/ } else @@ -226,14 +227,33 @@ vips_area_new( VipsCallbackFn free_fn, void *data ) area->sizeof_type = 0; #ifdef DEBUG - vips_area_number += 1; + vips_area_all = g_slist_prepend( vips_area_all, area ); printf( "vips_area_new: %p count = %d (%d in total)\n", - area, area->count, vips_area_number ); + area, area->count, + g_slist_length( vips_area_all ) ); #endif /*DEBUG*/ return( area ); } +void +vips__type_leak( void ) +{ +#ifdef DEBUG + if( vips_area_all ) { + GSList *p; + + printf( "VipsArea leaks:\n" ); + for( p = vips_area_all; p; p = p->next ) { + VipsArea *area = (VipsArea *) p->data; + + printf( "\t%p count = %d\n", area, area->count ); + } + printf( "%d in total\n", g_slist_length( vips_area_all ) ); + } +#endif /*DEBUG*/ +} + /** * vips_area_new_blob: * @free_fn: (scope async): @data will be freed with this function