2008-11-03 9 views
5

Estoy tratando de usar mtrace para detectar fugas de memoria en un programa fortran. Estoy usando el compilador de gfortran. Ver la entrada de Wikipedia para un ejemplo (de trabajo) C de mtrace: http://en.wikipedia.org/wiki/Mtracemtrace para un programa fortran

que probé en ambos sentidos, es decir, envolviendo el mtrace() y muntrace() y llamarlos desde el programa de Fortran, así como crear un programa en C, que directamente llame a mtrace() y muntrace(), además del código fortran que se está filtrando. Ambos enfoques no detectarán la pérdida de memoria, pero aquí presento solo el último.

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 

compilo con:

gfortran -g example.c leaky.f90 

Luego ejecutar con:

export MALLOC_TRACE=`pwd`/raw.txt; ./a.out 

Entonces analizar la salida raw.txtmtrace con:

mtrace a.out raw.txt 

y obtener:

No hay pérdidas de memoria.

¿Hay algo que esté haciendo mal, o algo que pueda hacer para dejar que mtrace encuentre la asignación de memoria forther permeable? Supongo que gfortran usa una llamada diferente malloc, que mtrace no rastrea ... De hecho, como escribí anteriormente, obtengo el mismo resultado si escribo un fortran principal que llamaría a (envuelto) mtrace() y muntrace().

EDITADO: Consideré otras opciones (incluso algunas no mencionadas aún aquí), pero el código actual que se está depurando se ejecuta en P6/AIX, por lo que Valgrind sería "simplemente" inconveniente (debe ejecutarse en una máquina diferente), mientras que Forcheck sería inconveniente (necesita funcionar en una máquina diferente) y caro (~ 3k $). En la actualidad mtrace sería la mejor solución, si funcionó.

editado de nuevo: Mi conjetura

supongo gfortran utiliza una llamada malloc diferente, que mtrace no rastrea ...

era correcta. Al mirar el ejecutable (ya sea con nm o readelf) no hay ninguna llamada malloc(), pero _gfortran_allocate_array - que tal vez llame a malloc). ¿Alguna otra idea?

editado de nuevo: he publicado la respuesta, pero no puedo aceptarlo (ir a http://stackoverflow.uservoice.com/pages/general/suggestions/39426 y solicitar la característica, es realmente necesario - no hay ganancia reputación quería)

Respuesta

1

Steve Kargl tenía la respuesta, que brevemente es que mtrace no encuentra ninguna fuga, porque no hay ninguna fuga si el compilador se ajusta al estándar: Ver http://gcc.gnu.org/ml/fortran/2008-11/msg00163.html para más detalles.

De hecho, no soy un gran experto fortran (soy mayormente C/C++/java), y también estaba usando otro compilador, que PERMITE fugas en tal condición (no lo mencioné a mantener la pregunta más fácil). Por lo tanto, pensé equivocadamente que la fuga estaba allí también con gfortran, que no es el caso (lo comprobé con la parte superior)

1

No soy un experto en mtrace, por lo que no puedo ayudar con eso. Le sugiero que pruebe la herramienta valgrind para encontrar fugas de memoria si está utilizando un sistema compatible. Usar valgrind para encontrar fugas de memoria es tan simple como llamar al valgrind --leak-check=full ./a.out.

1

Tengo experiencia en la depuración de programas Fortran, pero para ser sincero, no pude entender tu pregunta. Creo que es porque no tengo mucha experiencia en la depuración de C/C++ que difiera de Fortran. Sin embargo, creo que esto lo beneficiará:

El uso del compilador Intel con las siguientes opciones de compilación detectará casi cualquier pérdida de memoria, acceso a direcciones incorrectas o uso de puntero/variable sin inicializar durante el tiempo de ejecución.

Intel: -O0 -debug -traceback -check -ftrapuv

Para gfortran también que prácticamente se puede conseguir cualquiera de los errores anteriores con estas opciones del compilador.

gfortran: -g -O0 -fbounds-Check -Wuninitialized

Se imprimirá el rastreo de llamadas a subprogramas, hasta donde se produce el error. Siempre es útil compilar con dos compiladores diferentes y, en mi experiencia, casi no habrá pérdida de memoria después de esto.