Reputation: 17808
I'm trying to use mtrace
to detect memory leaks in a fortran program. I'm using the gfortran compiler. See the wikipedia entry for a (working) C example of mtrace: http://en.wikipedia.org/wiki/Mtrace
I tried both ways, i.e. wrapping the mtrace() and muntrace() and call them from the fortran program, as well as create a C program which directly call the mtrace() and muntrace(), besides the leaking fortran code in between. Both approaches will fail to detect the memory leak, but here I'm presenting only the latter.
example.c
#include <stdlib.h>
#include <mcheck.h>
extern void leaky_(); // this might be different on your system
// if it doesn't work, try to run:
// 1) gfortran leaky.f90 -c
// 2) nm leaky.o
// and then change this declaration and its use below
void main() {
mtrace();
leaky_();
muntrace();
}
leaky.f90
subroutine leaky()
real, allocatable, dimension(:) :: tmp
integer :: error
allocate (tmp(10), stat=error)
if (error /= 0) then
print*, "subroutine leaky could not allocate space for array tmp"
endif
tmp = 1
!of course the actual code makes more...
print*, ' subroutine leaky run '
return
end subroutine leaky
I compile with:
gfortran -g example.c leaky.f90
Then I run with:
export MALLOC_TRACE=`pwd`/raw.txt; ./a.out
Then I parse the raw.txt
mtrace
output with:
mtrace a.out raw.txt
and get:
No memory leaks.
Is there anything I'm doing wrong, or something I can do to let mtrace
find the leaky fortran memory allocation? I guess gfortran is using a different malloc
call, which mtrace
does not trace...
In fact, as I wrote above I get the same result if I write a fortran main which would call the (wrapped) mtrace()
and muntrace()
.
EDITED: I considered other options (including some not yet mentioned here), but the actual code being debugged runs on P6/AIX, so Valgrind would be "just" inconvenient (it needs to run on a different machine), whereas Forcheck would be inconvenient (it needs to run on a different machine) and expensive ( ~ 3k$). At present mtrace would be the best solution, if it worked.
EDITED again: My guess
I guess gfortran is using a different
malloc
call, whichmtrace
does not trace...
was correct. Looking into the executable (either with nm
or readelf
) there isn't any malloc()
call, but _gfortran_allocate_array
ones - which maybe will call malloc). Any other ideas?
EDITED again: I posted the answer but I cannot accept it (go to http://stackoverflow.uservoice.com/pages/general/suggestions/39426 and request the feature, it's really needed - no reputation gain wanted)
Upvotes: 5
Views: 2223
Reputation: 126
I have experience with debugging Fortran programs but to be honest I could not really understand your question. I think it is because I do not have much of C/C++ debugging experience which different to Fortran. Nevertheless I think this will benefit you:
Using the Intel compiler with the following compile options will detect almost any memory leak , wrong address access or using uninitialized pointer/variable during runtime.
intel: -O0 -debug -traceback -check -ftrapuv
For Gfortran also you can pretty much get any of the above errors with these compiler options.
gfortran: -g -O0 -fbounds-check -Wuninitialized
It will print the traceback of subroutine calls until where the error occurs. It is always helpful to compile with two different compilers and in my experience you will have almost no memory leak after this.
Upvotes: 1
Reputation: 17808
Steve Kargl had the answer, which briefly is that mtrace does not find any leak, because there isn't any leak if the compiler conforms to the standard: See http://gcc.gnu.org/ml/fortran/2008-11/msg00163.html for details.
In fact I'm not a big fortran expert (I'm mostly C/C++/java guy), and I was also using another compiler, which DOES leak in such a condition (I didn't mention that to keep the question easier). Thus I mistakenly thought that the leak was there also with gfortran, which is not the case (I checked with top)
Upvotes: 1
Reputation: 884
Valgrind is Linux only. For a windows product look at Forcheck. http://www.forcheck.nl/features.htm
Upvotes: 1