[Insight-users] memory leak check in ITK?

Feng Ma mafeng at hotmail . com
Fri, 26 Sep 2003 18:05:03 -0400


Hi, Luis:

  I got the results. One of them is related to the affine transform for 
resample image filter. I posted the valgrind results and my code here:

Valgrind reports:

==25148== Memcheck, a.k.a. Valgrind, a memory error detector for x86-linux.
==25148== Copyright (C) 2002-2003, and GNU GPL'd, by Julian Seward.
==25148== Using valgrind-20030725, a program supervision framework for 
x86-linux.
==25148== Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward.
==25148== Startup, with flags:
==25148==    --suppressions=/usr/local/lib/valgrind/default.supp
==25148==    --error-limit=no
==25148==    --leak-check=yes
==25148==    -v
==25148==    --show-reachable=yes
==25148==    --num-callers=50
==25148== Reading syms from /r2net/r2/fma/ITKTest/test/bin/fmatest
==25148== Reading syms from /lib/ld-2.2.4.so
==25148== Reading syms from /usr/local/lib/valgrind/vgskin_memcheck.so
==25148== Reading syms from /usr/local/lib/valgrind/valgrind.so
==25148== Reading syms from /usr/local/lib/valgrind/libpthread.so
==25148== Reading syms from /lib/libdl-2.2.4.so
==25148== Reading syms from /lib/i686/libm-2.2.4.so
==25148== Reading syms from /usr/local/lib/libstdc++.so.5.0.5
==25148== Reading syms from /usr/local/lib/libgcc_s.so.1
==25148== Reading syms from /lib/i686/libc-2.2.4.so
==25148== Reading suppressions file: /usr/local/lib/valgrind/default.supp
==25148== Estimated CPU clock rate is 997 MHz
==25148==
Input volume: size (512 512 304) spacing (1.00 1.00 1.00) origin (0.00 0.00 
0.00)
==25148== Warning: set address range perms: large range 159383552, a 0, v 0
Output volume: size (64 64 38) spacing (8.00 8.00 8.00) origin (0.00 0.00 
0.00)
Resample successful
Watershed successful
==25148== Warning: set address range perms: large range 159383552, a 1, v 1
==25148==
==25148== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 78 from 2)
--25148--
--25148-- supp:   40 __pthread_mutex_unlock/_IO_funlockfile
--25148-- supp:   38 
pthread_error/__pthread_mutex_destroy/_IO_default_finish
==25148== malloc/free: in use at exit: 11304 bytes in 14 blocks.
==25148== malloc/free: 2182 allocs, 2168 frees, 169816622 bytes allocated.
==25148==
==25148== searching for pointers to 14 not-freed blocks.
==25148== checked 6202344 bytes.
==25148==
==25148== 16 bytes in 1 blocks are definitely lost in loss record 1 of 5
==25148==    at 0x4002C90D: malloc (vg_replace_malloc.c:153)
==25148==    by 0x4002CE92: realloc (vg_replace_malloc.c:291)
==25148==    by 0x403F5064: __argz_append (argz-append.c:30)
==25148==    by 0x403923D6: __newlocale (newlocale.c:100)
==25148==    by 0x402F59AD: 
std::locale::facet::_S_create_c_locale(__locale_struct*&, char const*, 
__locale_struct*) (c++locale.cc:171)
==25148==    by 0x402ED139: std::locale::_Impl::_Impl(std::locale::facet**, 
unsigned, bool) (../../../../gcc-3.3.1/libstdc++-v3/src/localename.cc:226)
==25148==    by 0x402EA0E4: std::locale::classic() 
(../../../../gcc-3.3.1/libstdc++-v3/libsupc++/new:92)
==25148==    by 0x402E8BAC: std::locale::locale() 
(/r2/fma/gcc331Build/i686-pc-linux-gnu/libstdc++-v3/include/bits/locale_classes.h:179)
==25148==    by 0x402FC636: std::basic_filebuf<char, std::char_traits<char> 
 >::basic_filebuf() 
(/r2/fma/gcc331Build/i686-pc-linux-gnu/libstdc++-v3/include/streambuf:583)
==25148==    by 0x402FBAA1: __gnu_cxx::stdio_filebuf<char, 
std::char_traits<char> >::stdio_filebuf(_IO_FILE*, std::_Ios_Openmode, 
unsigned) 
(/r2/fma/gcc331Build/i686-pc-linux-gnu/libstdc++-v3/include/ext/stdio_filebuf.h:147)
==25148==    by 0x402E7DCF: std::ios_base::Init::_S_ios_create(bool) 
(../../../../gcc-3.3.1/libstdc++-v3/libsupc++/new:92)
==25148==    by 0x402E8464: std::ios_base::Init::Init() 
(../../../../gcc-3.3.1/libstdc++-v3/src/ios.cc:228)
==25148==    by 0x402E7B76: __static_initialization_and_destruction_0(int, 
int) 
(/r2/fma/gcc331Build/i686-pc-linux-gnu/libstdc++-v3/include/iostream:77)
==25148==    by 0x402E7B99: 
_GLOBAL__I__ZThn8_NSt14basic_iostreamIwSt11char_traitsIwEED0Ev.._.._.._.._gcc_3.3.1_libstdc___v3_src_io_inst.ccl5ZUua 
(/r2/fma/gcc331Build/i686-pc-linux-gnu/libstdc++-v3/include/bits/locale_facets.h:210)
==25148==    by 0x402E5B84: (within /usr/local/lib/libstdc++.so.5.0.5)
==25148==    by 0x402DE83D: (within /usr/local/lib/libstdc++.so.5.0.5)
==25148==    by 0x4000DAA6: _dl_init (dl-init.c:70)
==25148==    by 0x40001ED0: (within /lib/ld-2.2.4.so)
==25148==
==25148==
==25148== 24 bytes in 2 blocks are definitely lost in loss record 2 of 5
==25148==    at 0x4002CB02: __builtin_vec_new (vg_replace_malloc.c:197)
==25148==    by 0x4002CB6D: operator new[](unsigned) 
(vg_replace_malloc.c:210)
==25148==    by 0x8158A56: vnl_c_vector_alloc(int, int) 
(/space2/Devel/InsightToolkit-1.4.0/Utilities/vxl/vnl/vnl_c_vector.txx:362)
==25148==    by 0x815892C: vnl_c_vector<double>::allocate_Tptr(int) 
(/space2/Devel/InsightToolkit-1.4.0/Utilities/vxl/vnl/vnl_c_vector.txx:383)
==25148==    by 0x80E97D4: vnl_matrix_ref<double>::vnl_matrix_ref(unsigned, 
unsigned, double*) 
(/space2/Devel/InsightToolkit-1.4.0/Utilities/vxl/vnl/vnl_matrix_ref.h:46)
==25148==    by 0x80E979E: vnl_matrix_fixed<double, 3, 3>::operator 
vnl_matrix_ref<double> const() const 
(/r2/fma/ITK/1.4/Debug/include/InsightToolkit/Utilities/vxl/vnl/vnl_matrix_fixed.h:533)
==25148==    by 0x80E9655: itk::Matrix<double, 3, 3>::GetInverse() const 
(/r2/fma/ITK/1.4/Debug/include/InsightToolkit/Common/itkMatrix.txx:204)
==25148==    by 0x80E7E36: itk::AffineTransform<double, 
3>::RecomputeInverse() 
(/r2/fma/ITK/1.4/Debug/include/InsightToolkit/Common/itkAffineTransform.txx:591)
==25148==    by 0x80E7450: itk::AffineTransform<double, 3>::SetIdentity() 
(/r2/fma/ITK/1.4/Debug/include/InsightToolkit/Common/itkAffineTransform.h:193)
==25148==    by 0x80E6B14: int itkResampleDataBuffer<short, 3>(short*, int 
(&) [3], int, int, int*, double*, double*, short**, int*, double*, double*, 
int) (/r2net/r2/fma/ITKTest/ITKWrapLib/src/itkResample.cxx:42)
==25148==    by 0x80D55DC: itkResample3DShortDataBufferInC 
(/r2net/r2/fma/ITKTest/ITKWrapLib/src/itkResample.cxx:125)
==25148==    by 0x80D52C4: cmain (/r2net/r2/fma/ITKTest/test/src/test.c:82)
==25148==    by 0x80D4ED4: main (/r2net/r2/fma/ITKTest/test/src/main.cpp:4)
==25148==    by 0x40387656: __libc_start_main 
(../sysdeps/generic/libc-start.c:129)
==25148==    by 0x80D4DC0: (within /r2net/r2/fma/ITKTest/test/bin/fmatest)
==25148==
==25148==
==25148== 64 bytes in 1 blocks are still reachable in loss record 3 of 5
==25148==    at 0x4002C90D: malloc (vg_replace_malloc.c:153)
==25148==    by 0x403926BC: __newlocale (newlocale.c:162)
==25148==    by 0x402F59AD: 
std::locale::facet::_S_create_c_locale(__locale_struct*&, char const*, 
__locale_struct*) (c++locale.cc:171)
==25148==    by 0x402ED139: std::locale::_Impl::_Impl(std::locale::facet**, 
unsigned, bool) (../../../../gcc-3.3.1/libstdc++-v3/src/localename.cc:226)
==25148==    by 0x402EA0E4: std::locale::classic() 
(../../../../gcc-3.3.1/libstdc++-v3/libsupc++/new:92)
==25148==    by 0x402E8BAC: std::locale::locale() 
(/r2/fma/gcc331Build/i686-pc-linux-gnu/libstdc++-v3/include/bits/locale_classes.h:179)
==25148==    by 0x402FC636: std::basic_filebuf<char, std::char_traits<char> 
 >::basic_filebuf() 
(/r2/fma/gcc331Build/i686-pc-linux-gnu/libstdc++-v3/include/streambuf:583)
==25148==    by 0x402FBAA1: __gnu_cxx::stdio_filebuf<char, 
std::char_traits<char> >::stdio_filebuf(_IO_FILE*, std::_Ios_Openmode, 
unsigned) 
(/r2/fma/gcc331Build/i686-pc-linux-gnu/libstdc++-v3/include/ext/stdio_filebuf.h:147)
==25148==    by 0x402E7DCF: std::ios_base::Init::_S_ios_create(bool) 
(../../../../gcc-3.3.1/libstdc++-v3/libsupc++/new:92)
==25148==    by 0x402E8464: std::ios_base::Init::Init() 
(../../../../gcc-3.3.1/libstdc++-v3/src/ios.cc:228)
==25148==    by 0x402E7B76: __static_initialization_and_destruction_0(int, 
int) 
(/r2/fma/gcc331Build/i686-pc-linux-gnu/libstdc++-v3/include/iostream:77)
==25148==    by 0x402E7B99: 
_GLOBAL__I__ZThn8_NSt14basic_iostreamIwSt11char_traitsIwEED0Ev.._.._.._.._gcc_3.3.1_libstdc___v3_src_io_inst.ccl5ZUua 
(/r2/fma/gcc331Build/i686-pc-linux-gnu/libstdc++-v3/include/bits/locale_facets.h:210)
==25148==    by 0x402E5B84: (within /usr/local/lib/libstdc++.so.5.0.5)
==25148==    by 0x402DE83D: (within /usr/local/lib/libstdc++.so.5.0.5)
==25148==    by 0x4000DAA6: _dl_init (dl-init.c:70)
==25148==    by 0x40001ED0: (within /lib/ld-2.2.4.so)
==25148==
==25148==
==25148== 11000 bytes in 9 blocks are still reachable in loss record 5 of 5
==25148==    at 0x4002C9FD: __builtin_new (vg_replace_malloc.c:172)
==25148==    by 0x4002CA68: operator new(unsigned) (vg_replace_malloc.c:185)
==25148==    by 0x40332B2A: std::__default_alloc_template<true, 
0>::_S_chunk_alloc(unsigned, int&) 
(/r2/fma/gcc331Build/i686-pc-linux-gnu/libstdc++-v3/include/bits/stl_alloc.h:108)
==25148==    by 0x40332A3C: std::__default_alloc_template<true, 
0>::_S_refill(unsigned) 
(/r2/fma/gcc331Build/i686-pc-linux-gnu/libstdc++-v3/include/bits/stl_alloc.h:550)
==25148==    by 0x40332737: std::__default_alloc_template<true, 
0>::allocate(unsigned) 
(/r2/fma/gcc331Build/i686-pc-linux-gnu/libstdc++-v3/include/bits/stl_alloc.h:357)
==25148==    by 0x8141BA6: 
std::__simple_alloc<std::_List_node<itk::ObjectFactoryBase*>, 
std::__default_alloc_template<true, 0> >::allocate(unsigned) 
(/usr/local/include/c++/3.3.1/bits/stl_alloc.h:232)
==25148==    by 0x8141B79: std::_List_alloc_base<itk::ObjectFactoryBase*, 
std::allocator<itk::ObjectFactoryBase*>, true>::_M_get_node() 
(/usr/local/include/c++/3.3.1/bits/stl_list.h:275)
==25148==    by 0x8141B40: std::_List_base<itk::ObjectFactoryBase*, 
std::allocator<itk::ObjectFactoryBase*> 
 >::_List_base(std::allocator<itk::ObjectFactoryBase*> const&) 
(/usr/local/include/c++/3.3.1/bits/stl_list.h:304)
==25148==    by 0x8140F9B: std::list<itk::ObjectFactoryBase*, 
std::allocator<itk::ObjectFactoryBase*> 
 >::list(std::allocator<itk::ObjectFactoryBase*> const&) 
(/usr/local/include/c++/3.3.1/bits/stl_list.h:452)
==25148==    by 0x80DC17E: itk::ObjectFactoryBase::Initialize() 
(/space2/Devel/InsightToolkit-1.4.0/Code/Common/itkObjectFactoryBase.cxx:171)
==25148==    by 0x80DBEE0: itk::ObjectFactoryBase::CreateInstance(char 
const*) 
(/space2/Devel/InsightToolkit-1.4.0/Code/Common/itkObjectFactoryBase.cxx:115)
==25148==    by 0x80E8919: 
itk::ObjectFactory<itk::ResampleImageFilter<itk::Image<short, 3>, 
itk::Image<short, 3> > >::Create() 
(/r2/fma/ITK/1.4/Debug/include/InsightToolkit/Common/itkObjectFactory.h:52)
==25148==    by 0x80E87EE: itk::ResampleImageFilter<itk::Image<short, 3>, 
itk::Image<short, 3> >::New() 
(/r2/fma/ITK/1.4/Debug/include/InsightToolkit/BasicFilters/itkResampleImageFilter.h:77)
==25148==    by 0x80E6AD4: int itkResampleDataBuffer<short, 3>(short*, int 
(&) [3], int, int, int*, double*, double*, short**, int*, double*, double*, 
int) (/r2net/r2/fma/ITKTest/ITKWrapLib/src/itkResample.cxx:29)
==25148==    by 0x80D55DC: itkResample3DShortDataBufferInC 
(/r2net/r2/fma/ITKTest/ITKWrapLib/src/itkResample.cxx:125)
==25148==    by 0x80D52C4: cmain (/r2net/r2/fma/ITKTest/test/src/test.c:82)
==25148==    by 0x80D4ED4: main (/r2net/r2/fma/ITKTest/test/src/main.cpp:4)
==25148==    by 0x40387656: __libc_start_main 
(../sysdeps/generic/libc-start.c:129)
==25148==    by 0x80D4DC0: (within /r2net/r2/fma/ITKTest/test/bin/fmatest)
==25148==
==25148== LEAK SUMMARY:
==25148==    definitely lost: 40 bytes in 3 blocks.
==25148==    possibly lost:   0 bytes in 0 blocks.
==25148==    still reachable: 11064 bytes in 10 blocks.
==25148==         suppressed: 200 bytes in 1 blocks.
==25148==
--25148--     TT/TC: 0 tc sectors discarded.
--25148--            11322 chainings, 0 unchainings.
--25148-- translate: new     17176 (264522 -> 3542893; ratio 133:10)
--25148--            discard 0 (0 -> 0; ratio 0:10).
--25148--  dispatch: 9126900000 jumps (bb entries), of which 3183030992 
(34%) were unchained.
--25148--            182628/17242078 major/minor sched events.  17011469 
tt_fast misses.
--25148-- reg-alloc: 3556 t-req-spill, 653228+18449 orig+spill uis, 85799 
total-reg-r.
--25148--    sanity: 182629 cheap, 7306 expensive checks.
--25148--    ccalls: 87757 C calls, 59% saves+restores avoided (309252 
bytes)
--25148--            119583 args, avg 0.87 setup instrs each (30062 bytes)
--25148--            0% clear the stack (263271 bytes)
--25148--            28888 retvals, 30% of reg-reg movs avoided (16782 
bytes)


My code: itkResample.cxx

#include <fstream>
#include <string>
#include "itkCastImageFilter.h"
#include "itkResampleImageFilter.h"
#include "itkNearestNeighborInterpolateImageFunction.h"
#include "itkLinearInterpolateImageFunction.h"
#include "itkWrapCommon.h"
#include "itkResample.h"

extern "C" {
#include <string.h>
#include <stdio.h>
}

template <class TPixel, unsigned int VImageDimension>
int itkResampleDataBuffer(TPixel *inBuffer, int (&zoomOut)[VImageDimension],
						  int interpolateType, int defaultVoxelValue,
						  int *inSize, double *inSpacing, double *inOrigin,
						  TPixel **outBuffer, int *outSize,
						  double *outSpacing, double *outOrigin,
						  int outputMemCopyOption)
{
  //  const int VImageDimension = dim;
  int i, inputVoxNum, outputVoxNum;

  typedef itk::Image<TPixel, VImageDimension> ImageType;

  typedef itk::ResampleImageFilter<ImageType, ImageType>  
ResampleFilterType;
  typename ResampleFilterType::Pointer resampleFilter = 
ResampleFilterType::New();

  typedef  itk::NearestNeighborInterpolateImageFunction<
	ImageType, double >  NNInterpolatorType;
  typename NNInterpolatorType::Pointer nearestNeighborInterpolator =
	NNInterpolatorType::New();

  typedef itk::LinearInterpolateImageFunction<
	ImageType, double >  LinearInterpolatorType;
  typename LinearInterpolatorType::Pointer linearInterpolator = 
LinearInterpolatorType::New();

  typedef itk::AffineTransform<double, VImageDimension> TransformType;
  typename TransformType::Pointer transform = TransformType::New();
  transform->SetIdentity();

  resampleFilter->SetTransform(transform);
  if( interpolateType == RESAMPLE_INTERPOLATE_LINEAR)
	resampleFilter->SetInterpolator(linearInterpolator);
  else
	resampleFilter->SetInterpolator(nearestNeighborInterpolator);

  resampleFilter->SetDefaultPixelValue(defaultVoxelValue);

  typename ImageType::Pointer outputImage = NULL;
  typename ImageType::Pointer inputImage = ImageType::New();
  typename ImageType::RegionType inputRegion;
  typename ImageType::RegionType outputRegion;
  typename ImageType::RegionType::IndexType inputIndex;
  typename ImageType::RegionType::SizeType inputSize;
  typename ImageType::RegionType::SizeType outputSize;

  inputVoxNum = 1;
  outputVoxNum = 1;
  for(i = 0; i < VImageDimension; i ++){
	inputIndex[i] = 0;
	inputSize[i] = inSize[i];
	inputVoxNum *= inSize[i];
	outputSize[i] = outSize[i];
	outputVoxNum *= outSize[i];
  }

  inputRegion.SetIndex(inputIndex);
  inputRegion.SetSize(inputSize);
  inputImage->SetRegions(inputRegion);
  inputImage->SetSpacing(inSpacing);
  inputImage->SetOrigin(inOrigin);

  typename itk::ImportImageContainer<long unsigned int, TPixel>::Pointer 
importer;
  importer = itk::ImportImageContainer<long unsigned int, TPixel>::New();
  importer->Initialize();
  importer->SetImportPointer(inBuffer, inputVoxNum, false);
  inputImage->SetPixelContainer(importer);

  resampleFilter->SetOutputSpacing(outSpacing);
  resampleFilter->SetOutputOrigin(outOrigin);
  resampleFilter->SetSize(outputSize);
  resampleFilter->SetInput(inputImage);
  resampleFilter->Update();

  outputImage = resampleFilter->GetOutput();
  if(outputMemCopyOption == OUTPUT_MEM_BORROW){
	outputImage->GetPixelContainer()->SetContainerManageMemory(false);//non-copy
	*outBuffer = outputImage->GetPixelContainer()->GetImportPointer();
  }
  else
	memcpy((TPixel *)(*outBuffer),
		   outputImage->GetPixelContainer()->GetBufferPointer(),
		   outputVoxNum*sizeof(TPixel));

  return 0;
}


extern "C" int itkResample3DShortDataBufferInC(short *inBuffer, int 
*_zoomOut,
											   int interpolateType,
											   int defaultVoxelValue,
											   int *inSize, double *inSpacing,
											   double *inOrigin,
											   short **outBuffer, int *outSize,
											   double *outSpacing,
											   double *outOrigin)
{
  int zoomOut[3], i;
  //instantiation purpose
  for(i = 0; i < 3; i ++)
	zoomOut[i] = _zoomOut[i];

  if( *outBuffer == NULL)
	return 1; //C caller should allocate output memory first

  return(itkResampleDataBuffer(inBuffer, zoomOut, interpolateType,
							   defaultVoxelValue,
							   inSize, inSpacing, inOrigin, outBuffer,
							   outSize, outSpacing, outOrigin, OUTPUT_MEM_COPY));
}


Thanks a lot.

-Feng


>From: Luis Ibanez <luis . ibanez at kitware . com>
>To: Feng Ma <mafeng at hotmail . com>
>CC: insight-users at itk . org
>Subject: Re: [Insight-users] memory leak check in ITK?
>Date: Fri, 26 Sep 2003 15:28:37 -0400
>
>
>Hi Feng,
>
>Thanks for your report,
>
>There may still be a memory leak related to the use
>of a  vnl_c_vector.  However the current Valgrind
>report may not be sufficient to locate the source
>of the leak.
>
>By default Valgrind reports only 4 levels of the callstack,
>
>Please run your test again, but this time using the option:
>
>         valgrind --num-callers=50
>
>That will display at least 50 levels of the call stack.
>
>Hopefully the real source of the leak reported by vnl_c_vector
>will show up in the new report.
>
>
>Please let us know what you get,
>
>
>Thanks
>
>
>
>   Luis
>
>
>

_________________________________________________________________
Instant message with integrated webcam using MSN Messenger 6.0. Try it now 
FREE!  http://msnmessenger-download . com