This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
Re: valgrind reports "definitely lost" memory for very simple codes
- From: Andre Vehreschild <vehre at gmx dot de>
- To: Damian Rouson <damian at sourceryinstitute dot org>
- Cc: Fortran List <fortran at gcc dot gnu dot org>, "Clune, Thomas L. \(GSFC-6060\)" <Thomas dot L dot Clune at nasa dot gov>, Weiyuan Jiang <weiyuan dot jiang at nasa dot gov>
- Date: Fri, 8 May 2015 14:15:58 +0200
- Subject: Re: valgrind reports "definitely lost" memory for very simple codes
- Authentication-results: sourceware.org; auth=none
- References: <3EAB6301-2309-4012-922F-777AD6722669 at sourceryinstitute dot org>
Hi Damian,
in case you didn't get a reply yet:
I have been touching some of the aspects involved with allocatable components
and there have some insight on what is going on. Let's look at the examples:
intrinsic-variable.f90: Lost 4 byte, correctly detected by valgrind.
The pseudo-code generated for this example show one alloc and no free,
i.e., gfortran fault.
empty-derived-type.f90: Lost 1 byte, correctly detected by valgrind.
Here we encounter a special case: Some OS don't allow allocation of
zero bytes of memory. ElectricFence also flags those as errors,
therefore gfortran allocates at least one byte for empty types.
Nevertheless the pseudo-code shows the same: one alloc, no free ->
gfortran fault.
dt-with-component.f90: Lost 12 byte, correctly detected by valgrind.
The pseudo-code shows one calloc of 8 bytes for the definitely_lost
structure and one malloc of 4 bytes for the allocatable subcomponent.
There is one free for the memory of b. But this free is only executed,
when the definitely_lost%b was initialized before the malloc(4), i.e.,
in the current context it is never executed -> both missing frees are
gfortran's fault.
still-reachable.f90: Again correctly analyzed by valgrind. The free() is
missing for components memory. This is merely a variant of
dt-with-component.f90, although it is just differently reported.
I hope this little analysis helped somehow. The more complicated task will be
to figure where the missing frees are to inserted.
May be some other gfortraners like to jump in with advise or corrections of my
analysis?!
Regards,
Andre
On Thu, 7 May 2015 20:49:53 -0700
Damian Rouson <damian@sourceryinstitute.org> wrote:
> GFortran Developers,
>
> Below are several very short programs in which valgrind reports memory
> leaks. Based on what Iâve read
> (http://valgrind.org/docs/manual/faq.html#faq.deflost), I assume the
> âindirectly lostâ memory is just a secondary effect of the definitely lost
> memory and the âstill reachableâ memory is presumably not related to a bug.
> These codes are so simple that it seems more likely that valgrind is
> incorrect than that the compiler has bugs, but could someone please explain
> the âdefinitely lostâ reports?
>
> One indication that there are no memory leaks is that, if I wrap loops around
> the executable lines in these codes, valgrind reports the same amount of
> memory lost independent of the number of loop iterations. I am working on
> isolating the simplest case(s) for which the memory grows over time and will
> submit any such case(s) via Bugzilla.
>
> Damian
>
>
> $ gfortran --version
> GNU Fortran (GCC) 6.0.0 20150503 (experimental)
>
> $ cat intrinsic-variable.f90
>
> real, allocatable :: x
> x=0.
> end
>
> $ gfortran intrinsic-variable.f90
> $ valgrind ./a.out
> ==3969== Memcheck, a memory error detector
> ==3969== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
> ==3969== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
> ==3969== Command: ./a.out
> ==3969==
> ==3969==
> ==3969== HEAP SUMMARY:
> ==3969== in use at exit: 4 bytes in 1 blocks
> ==3969== total heap usage: 25 allocs, 24 frees, 12,706 bytes allocated
> ==3969==
> ==3969== LEAK SUMMARY:
> ==3969== definitely lost: 4 bytes in 1 blocks
> ==3969== indirectly lost: 0 bytes in 0 blocks
> ==3969== possibly lost: 0 bytes in 0 blocks
> ==3969== still reachable: 0 bytes in 0 blocks
> ==3969== suppressed: 0 bytes in 0 blocks
> ==3969== Rerun with --leak-check=full to see details of leaked memory
> ==3969==
> ==3969== For counts of detected and suppressed errors, rerun with: -v
> ==3969== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
>
>
> $ cat empty-derived-type.f90
>
> type subdata
> end type
> type(subdata), allocatable :: definitely_lost
> definitely_lost=subdata()
> end
>
> $ gfortran empty-derived-type.f90
> $ valgrind ./a.out
> ==3986== Memcheck, a memory error detector
> ==3986== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
> ==3986== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
> ==3986== Command: ./a.out
> ==3986==
> ==3986==
> ==3986== HEAP SUMMARY:
> ==3986== in use at exit: 1 bytes in 1 blocks
> ==3986== total heap usage: 25 allocs, 24 frees, 12,703 bytes allocated
> ==3986==
> ==3986== LEAK SUMMARY:
> ==3986== definitely lost: 1 bytes in 1 blocks
> ==3986== indirectly lost: 0 bytes in 0 blocks
> ==3986== possibly lost: 0 bytes in 0 blocks
> ==3986== still reachable: 0 bytes in 0 blocks
> ==3986== suppressed: 0 bytes in 0 blocks
> ==3986== Rerun with --leak-check=full to see details of leaked memory
> ==3986==
> ==3986== For counts of detected and suppressed errors, rerun with: -v
> ==3986== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
>
>
> $ cat dt-with-component.f90
>
> type subdata
> real, allocatable :: b
> end type
> type(subdata), allocatable :: definitely_lost
> definitely_lost=subdata()
> end
>
> $ gfortran dt-with-component.f90
> $ valgrind ./a.out
> ==3999== Memcheck, a memory error detector
> ==3999== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
> ==3999== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
> ==3999== Command: ./a.out
> ==3999==
> ==3999==
> ==3999== HEAP SUMMARY:
> ==3999== in use at exit: 12 bytes in 2 blocks
> ==3999== total heap usage: 26 allocs, 24 frees, 12,714 bytes allocated
> ==3999==
> ==3999== LEAK SUMMARY:
> ==3999== definitely lost: 8 bytes in 1 blocks
> ==3999== indirectly lost: 4 bytes in 1 blocks
> ==3999== possibly lost: 0 bytes in 0 blocks
> ==3999== still reachable: 0 bytes in 0 blocks
> ==3999== suppressed: 0 bytes in 0 blocks
> ==3999== Rerun with --leak-check=full to see details of leaked memory
> ==3999==
> ==3999== For counts of detected and suppressed errors, rerun with: -v
> ==3999== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
>
>
> $ cat still-reachable.f90
>
> type subdata
> real, allocatable :: b
> end type
> type(subdata) :: still_reachable
> still_reachable=subdata()
> end
>
> $ gfortran still-reachable.f90
> $ valgrind ./a.out
> ==4012== Memcheck, a memory error detector
> ==4012== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
> ==4012== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
> ==4012== Command: ./a.out
> ==4012==
> ==4012==
> ==4012== HEAP SUMMARY:
> ==4012== in use at exit: 4 bytes in 1 blocks
> ==4012== total heap usage: 25 allocs, 24 frees, 12,706 bytes allocated
> ==4012==
> ==4012== LEAK SUMMARY:
> ==4012== definitely lost: 0 bytes in 0 blocks
> ==4012== indirectly lost: 0 bytes in 0 blocks
> ==4012== possibly lost: 0 bytes in 0 blocks
> ==4012== still reachable: 4 bytes in 1 blocks
> ==4012== suppressed: 0 bytes in 0 blocks
> ==4012== Rerun with --leak-check=full to see details of leaked memory
> ==4012==
> ==4012== For counts of detected and suppressed errors, rerun with: -v
> ==4012== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
>
--
Andre Vehreschild * Email: vehre ad gmx dot de