[Insight-users] memory leak check in ITK?

Luis Ibanez luis . ibanez at kitware . com
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



-------------------
Feng Ma wrote:
> Hi, Luis:
> 
>  Thanks for the help. I did the modification as instructed. It does fix 
> some meory leakage: 48 bytes definitely lost and 72 possibly lost. But I 
> saw some new memory leak and appear more subtle to me.
> 
> ==9873== Copyright (C) 2002-2003, and GNU GPL'd, by Julian Seward.
> ==9873== Using valgrind-20030725, a program supervision framework for 
> x86-linux.
> ==9873== Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward.
> ==9873== Startup, with flags:
> ==9873==    --suppressions=/usr/local/lib/valgrind/default.supp
> ==9873==    --error-limit=no
> ==9873==    --leak-check=yes
> ==9873==    -v
> ==9873==    --show-reachable=yes
> ==9873== Reading syms from /r2net/r2/fma/ITKTest/test/bin/fmatest
> ==9873== Reading syms from /lib/ld-2.2.4.so
> ==9873== Reading syms from /usr/local/lib/valgrind/vgskin_memcheck.so
> ==9873== Reading syms from /usr/local/lib/valgrind/valgrind.so
> ==9873== Reading syms from /usr/local/lib/valgrind/libpthread.so
> ==9873== Reading syms from /lib/libdl-2.2.4.so
> ==9873== Reading syms from /lib/i686/libm-2.2.4.so
> ==9873== Reading syms from /usr/local/lib/libstdc++.so.5.0.5
> ==9873== Reading syms from /usr/local/lib/libgcc_s.so.1
> ==9873== Reading syms from /lib/i686/libc-2.2.4.so
> ==9873== Reading suppressions file: /usr/local/lib/valgrind/default.supp
> ==9873== Estimated CPU clock rate is 998 MHz
> ==9873==
> Input volume: size (512 512 304) spacing (1.00 1.00 1.00) origin (0.00 
> 0.00 0.00)
> ==9873== 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
> ==9873== Warning: set address range perms: large range 159383552, a 1, v 1
> ==9873==
> ==9873== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 78 from 2)
> --9873--
> --9873-- supp:   40 __pthread_mutex_unlock/_IO_funlockfile
> --9873-- supp:   38 
> pthread_error/__pthread_mutex_destroy/_IO_default_finish
> ==9873== malloc/free: in use at exit: 11304 bytes in 14 blocks.
> ==9873== malloc/free: 2182 allocs, 2168 frees, 169816622 bytes allocated.
> ==9873==
> ==9873== searching for pointers to 14 not-freed blocks.
> ==9873== checked 6198744 bytes.
> ==9873==
> ==9873== 16 bytes in 1 blocks are definitely lost in loss record 1 of 5
> ==9873==    at 0x4002C90D: malloc (vg_replace_malloc.c:153)
> ==9873==    by 0x4002CE92: realloc (vg_replace_malloc.c:291)
> ==9873==    by 0x403F5064: __argz_append (argz-append.c:30)
> ==9873==    by 0x403923D6: __newlocale (newlocale.c:100)
> ==9873==
> ==9873==
> ==9873== 24 bytes in 2 blocks are definitely lost in loss record 2 of 5
> ==9873==    at 0x4002CB02: __builtin_vec_new (vg_replace_malloc.c:197)
> ==9873==    by 0x4002CB6D: operator new[](unsigned) 
> (vg_replace_malloc.c:210)
> ==9873==    by 0x8158A56: vnl_c_vector_alloc(int, int) 
> (/space2/Devel/InsightToolkit-1.4.0/Utilities/vxl/vnl/vnl_c_vector.txx:362)
> ==9873==    by 0x815892C: vnl_c_vector<double>::allocate_Tptr(int) 
> (/space2/Devel/InsightToolkit-1.4.0/Utilities/vxl/vnl/vnl_c_vector.txx:383)
> ==9873==
> ==9873==
> ==9873== 64 bytes in 1 blocks are still reachable in loss record 3 of 5
> ==9873==    at 0x4002C90D: malloc (vg_replace_malloc.c:153)
> ==9873==    by 0x403926BC: __newlocale (newlocale.c:162)
> ==9873==    by 0x402F59AD: 
> std::locale::facet::_S_create_c_locale(__locale_struct*&, char const*, 
> __locale_struct*) (c++locale.cc:171)
> ==9873==    by 0x402ED139: 
> std::locale::_Impl::_Impl(std::locale::facet**, unsigned, bool) 
> (../../../../gcc-3.3.1/libstdc++-v3/src/localename.cc:226)
> ==9873==
> ==9873==
> ==9873== 11000 bytes in 9 blocks are still reachable in loss record 5 of 5
> ==9873==    at 0x4002C9FD: __builtin_new (vg_replace_malloc.c:172)
> ==9873==    by 0x4002CA68: operator new(unsigned) (vg_replace_malloc.c:185)
> ==9873==    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) 
> 
> ==9873==    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) 
> 
> ==9873==
> ==9873== LEAK SUMMARY:
> ==9873==    definitely lost: 40 bytes in 3 blocks.
> ==9873==    possibly lost:   0 bytes in 0 blocks.
> ==9873==    still reachable: 11064 bytes in 10 blocks.
> ==9873==         suppressed: 200 bytes in 1 blocks.
> ==9873==
> --9873--     TT/TC: 0 tc sectors discarded.
> --9873--            11322 chainings, 0 unchainings.
> --9873-- translate: new     17176 (264522 -> 3542893; ratio 133:10)
> --9873--            discard 0 (0 -> 0; ratio 0:10).
> --9873--  dispatch: 9126900000 jumps (bb entries), of which 3183030992 
> (34%) were unchained.
> --9873--            182628/17242078 major/minor sched events.  17011469 
> tt_fast misses.
> --9873-- reg-alloc: 3556 t-req-spill, 653228+18449 orig+spill uis, 85799 
> total-reg-r.
> --9873--    sanity: 182629 cheap, 7306 expensive checks.
> --9873--    ccalls: 87757 C calls, 59% saves+restores avoided (309252 
> bytes)
> --9873--            119583 args, avg 0.87 setup instrs each (30062 bytes)
> --9873--            0% clear the stack (263271 bytes)
> --9873--            28888 retvals, 30% of reg-reg movs avoided (16782 
> bytes)
> 
> 
> 
> 
>> 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: Thu, 25 Sep 2003 22:49:36 -0400
>>
>> Hi Feng,
>>
>>
>> Thanks for your report.
>>
>> There is a chance that a memory leak is taking
>> place in this filter.
>>
>>
>> Could you please try the following experiment:
>>
>> goto Insight/Code/Agorithms/itkWatershedSegmenter.txx
>>
>> and just before line 595 insert the following lines:
>>
>>
>> --------------------------------------------
>>    if (m_Connectivity.index != 0)
>>      {
>>      delete[] m_Connectivity.index;
>>      }
>>
>>    if (m_Connectivity.direction !=0 )
>>      {
>>      delete[] m_Connectivity.direction;
>>      }
>> -------------------------------------------
>>
>> // then the code should continue with:
>>
>>
>>   m_Connectivity.index = new unsigned int[m_Connectivity.size];
>>   m_Connectivity.direction
>>     = new typename InputImageType::OffsetType[m_Connectivity.size];
>>
>> ----------------------------------------------
>>
>>
>> What may be happening is that the method  GenerateConnectivity()
>> is being called twice (or more).  This method allocates memory
>> for the direction and the index, but it is not checking if there
>> were previous allocations.
>>
>> In the fix above, the potentially existing allocated
>> memory is released before invoking "new" again.
>>
>>
>> Please let us know if after inserting these lines, the
>> report from Valgrind improves or not.
>>
>> It this happens to help, we will include this fix in the
>> repository as soon as it is defrozen.
>>
>>
>>
>>
>> Thanks,
>>
>>
>>   Luis
>>
>>
>>
>> ------------------
>> Feng Ma wrote:
>>
>>> Hi,
>>>
>>>  I am using ITK and carefully checking memory leak in my project. 
>>> Wonderful what kind of memory checking tools ITK developers are using 
>>> to make sure no memory leakage.
>>>
>>>  I am using valgrind to check my program, which performs watershed on 
>>> an input image. I got the memory leakage report from valgrind and 
>>> posted here. I am wondering if valgrind is capable enough to check 
>>> ITK memory allocation since ITK is pretty complicated and how much I 
>>> should concern with its report.
>>>
>>>
>>> ==7944== LEAK SUMMARY:
>>> ==7944==    definitely lost: 64 bytes in 4 blocks.
>>> ==7944==    possibly lost:   72 bytes in 1 blocks.
>>> ==7944==    still reachable: 11064 bytes in 10 blocks.
>>> ==7944==         suppressed: 200 bytes in 1 blocks.
>>> ==7944==
>>> --7944--     TT/TC: 0 tc sectors discarded.
>>> --7944--            11330 chainings, 0 unchainings.
>>> --7944-- translate: new     17170 (264458 -> 3541953; ratio 133:10)
>>> --7944--            discard 0 (0 -> 0; ratio 0:10).
>>> --7944--  dispatch: 9126900000 jumps (bb entries), of which 
>>> 3185798345 (34%) were unchained.
>>> --7944--            182628/6169850 major/minor sched events.  5939243 
>>> tt_fast misses.
>>> --7944-- reg-alloc: 3556 t-req-spill, 653056+18449 orig+spill uis, 
>>> 85773 total-reg-r.
>>> --7944--    sanity: 182629 cheap, 7306 expensive checks.
>>> --7944--    ccalls: 87739 C calls, 59% saves+restores avoided (309178 
>>> bytes)
>>> --7944--            119561 args, avg 0.87 setup instrs each (30056 
>>> bytes)
>>> --7944--            0% clear the stack (263217 bytes)
>>> --7944--            28876 retvals, 30% of reg-reg movs avoided (16770 
>>> bytes)
>>>
>>> --7944-- supp:   40 __pthread_mutex_unlock/_IO_funlockfile
>>> --7944-- supp:   38 
>>> pthread_error/__pthread_mutex_destroy/_IO_default_finish
>>> ==7944== malloc/free: in use at exit: 11400 bytes in 16 blocks.
>>> ==7944== malloc/free: 2182 allocs, 2166 frees, 169816622 bytes 
>>> allocated.
>>> ==7944==
>>> ==7944== searching for pointers to 16 not-freed blocks.
>>> ==7944== checked 6201272 bytes.
>>> ==7944==
>>> ==7944== 16 bytes in 1 blocks are definitely lost in loss record 1 of 6
>>> ==7944==    at 0x4002C90D: malloc (vg_replace_malloc.c:153)
>>> ==7944==    by 0x4002CE92: realloc (vg_replace_malloc.c:291)
>>> ==7944==    by 0x403F5064: __argz_append (argz-append.c:30)
>>> ==7944==    by 0x403923D6: __newlocale (newlocale.c:100)
>>> ==7944== 48 bytes in 3 blocks are definitely lost in loss record 2 of 6
>>> ==7944==    at 0x4002CB02: __builtin_vec_new (vg_replace_malloc.c:197)
>>> ==7944==    by 0x4002CB6D: operator new[](unsigned) 
>>> (vg_replace_malloc.c:210)
>>> ==7944==    by 0x810C020: itk::watershed::Segmenter<itk::Image<float, 
>>> 3>::GenerateConnectivity() 
>>> (/r2/fma/ITK/1.4/Debug/include/InsightToolkit/Algorithms/itkWatershedSegmenter.txx:595) 
>>>
>>>
>>> ==7944==    by 0x810A4C6: itk::watershed::Segmenter<itk::Image<float, 
>>> 3>  >::GenerateData() 
>>> (/r2/fma/ITK/1.4/Debug/include/InsightToolkit/Algorithms/itkWatershedSegmenter.txx:178) 
>>>
>>>
>>> ==7944==
>>> ==7944==
>>> ==7944== 64 bytes in 1 blocks are still reachable in loss record 3 of 6
>>> ==7944==    at 0x4002C90D: malloc (vg_replace_malloc.c:153)
>>> ==7944==    by 0x403926BC: __newlocale (newlocale.c:162)
>>> ==7944==    by 0x402F59AD: 
>>> std::locale::facet::_S_create_c_locale(__locale_struct*&, char 
>>> const*, __locale_struct*) (c++locale.cc:171)
>>> ==7944==    by 0x402ED139: 
>>> std::locale::_Impl::_Impl(std::locale::facet**, unsigned, bool) 
>>> (../../../../gcc-3.3.1/libstdc++-v3/src/localename.cc:226)
>>> ==7944==
>>> ==7944==
>>> ==7944== 72 bytes in 1 blocks are possibly lost in loss record 4 of 6
>>> ==7944==    at 0x4002CB02: __builtin_vec_new (vg_replace_malloc.c:197)
>>> ==7944==    by 0x4002CB6D: operator new[](unsigned) 
>>> (vg_replace_malloc.c:210)
>>> ==7944==    by 0x810C049: itk::watershed::Segmenter<itk::Image<float, 
>>> 3>  >::GenerateConnectivity() 
>>> (/r2/fma/ITK/1.4/Debug/include/InsightToolkit/Algorithms/itkWatershedSegmenter.txx:596) 
>>>
>>>
>>> ==7944==    by 0x810A4C6: itk::watershed::Segmenter<itk::Image<float, 
>>> 3>  >::GenerateData() 
>>> (/r2/fma/ITK/1.4/Debug/include/InsightToolkit/Algorithms/itkWatershedSegmenter.txx:178) 
>>>
>>>
>>> ==7944==
>>> ==7944==
>>> ==7944== 11000 bytes in 9 blocks are still reachable in loss record 6 
>>> of 6
>>> ==7944==    at 0x4002C9FD: __builtin_new (vg_replace_malloc.c:172)
>>> ==7944==    by 0x4002CA68: operator new(unsigned) 
>>> (vg_replace_malloc.c:185)
>>> ==7944==    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) 
>>>
>>>
>>> ==7944==    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) 
>>>
>>>
>>> ==7944==
>>>
>>>  Thanks a lot in advance.
>>>
>>> -Feng
>>>
>>> _________________________________________________________________
>>> High-speed Internet access as low as $29.95/month (depending on the 
>>> local service providers in your area). Click here.   
>>> https://broadband . msn . com
>>>
>>> _______________________________________________
>>> Insight-users mailing list
>>> Insight-users at itk . org
>>> http://www . itk . org/mailman/listinfo/insight-users
>>>
>>
>>
>>
>>
> 
> _________________________________________________________________
> Instant message during games with MSN Messenger 6.0. Download it now 
> FREE!  http://msnmessenger-download . com
> 
>