[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