c - write - fortran 77 download
mtrace para un programa fortran (4)
Estoy tratando de usar mtrace
para detectar fugas de memoria en un programa fortran. Estoy usando el compilador de gfortran. Vea la entrada de la wikipedia para un ejemplo C (de trabajo) de mtrace: http://en.wikipedia.org/wiki/Mtrace
Intenté en ambos sentidos, es decir, envolver el mtrace () y el muntrace () y llamarlos desde el programa fortran, así como crear un programa C que llame directamente a mtrace () y muntrace (), además del código fortran que se filtra entre ellos. Ambos enfoques no detectarán la pérdida de memoria, pero aquí presento solo el último.
ejemplo.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 corro con:
export MALLOC_TRACE=`pwd`/raw.txt; ./a.out
Luego raw.txt
el raw.txt
la raw.txt
mtrace
con:
mtrace a.out raw.txt
y obten:
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 mtrace
permeable? Supongo que Gfortran está utilizando una llamada malloc
diferente, que mtrace
no rastrea ... De hecho, como escribí anteriormente, obtengo el mismo resultado si escribo un fortran principal que llamaría a (wrapped) mtrace()
y muntrace()
.
EDITADO: Consideré otras opciones (incluso algunas que aún no se mencionan aquí), pero el código real 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 estaría inconveniente (necesita ejecutarse en una máquina diferente) y costoso (~ 3k $). En la actualidad mtrace sería la mejor solución, si funcionó.
EDITADO de nuevo: mi suposición
Supongo que gfortran usa una llamada
malloc
diferente, quemtrace
no rastrea ...
era correcto Al examinar el ejecutable (ya sea con nm
o con readelf
) no hay ninguna llamada malloc()
, pero _gfortran_allocate_array
unos - que tal vez llame malloc). ¿Alguna otra idea?
EDITADO de nuevo: Publiqué la respuesta, pero no puedo aceptarla (vaya a http://stackoverflow.uservoice.com/pages/general/suggestions/39426 y solicite la función, es realmente necesaria, no se requiere ganancia de reputación)
No soy un experto en mtrace, así 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 a valgrind --leak-check=full ./a.out
.
Valgrind es solo Linux. Para ver un producto de Windows en Forcheck. http://www.forcheck.nl/features.htm
Steve Kargl tuvo la respuesta, que brevemente es que mtrace no encuentra ninguna fuga, porque no hay ninguna fuga si el compilador cumple con el estándar: ver http://gcc.gnu.org/ml/fortran/2008-11 /msg00163.html para más detalles.
De hecho, no soy un gran experto (soy mayormente C / C ++ / chico java), y también estaba usando otro compilador, que PIERDE en tal condición (no lo mencioné para mantener la pregunta más fácil) ) Por lo tanto, erróneamente pensé que la fuga estaba allí también con gfortran, que no es el caso (lo comprobé con la parte superior)
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 te beneficiará:
El uso del compilador Intel con las siguientes opciones de compilación detectará casi cualquier fuga de memoria, acceso incorrecto a la dirección o el uso de un puntero / variable sin inicializar durante el tiempo de ejecución.
Intel: -O0 -debug -traceback -check -ftrapuv
Para Gfortran también puedes obtener cualquiera de los errores anteriores con estas opciones de compilación.
gfortran: -g -O0 -fbounds-check -Wuninitialized
Imprimirá el rastreo de llamadas de subrutina hasta que ocurra 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.