views:

641

answers:

3

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, which mtrace 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)

+1  A: 

I'm not an expert on mtrace, so I can't help with that. I would suggest that you try the valgrind tool to find memory-leaks if you are using a supported system. Using valgrind for finding memory-leaks is as simple as calling valgrind --leak-check=full ./a.out.

Zayenz
A: 

Valgrind is Linux only. For a windows product look at Forcheck. http://www.forcheck.nl/features.htm

SumoRunner
+1  A: 

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)

Davide