mtrace per un programma fortran
-
06-07-2019 - |
Domanda
Sto cercando di usare mtrace
per rilevare perdite di memoria in un programma fortran. Sto usando il compilatore gfortran. Vedi la voce wikipedia per un esempio C di lavoro (funzionante) di mtrace: http://en.wikipedia.org/ wiki / Mtrace
Ho provato in entrambi i modi, ovvero avvolgendo mtrace () e muntrace () e chiamandoli dal programma fortran, oltre a creare un programma C che chiama direttamente mtrace () e muntrace (), oltre al codice fortran che perde nel mezzo. Entrambi gli approcci non riusciranno a rilevare la perdita di memoria, ma qui sto presentando solo quest'ultimo.
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
Quindi corro con:
export MALLOC_TRACE=`pwd`/raw.txt; ./a.out
Quindi analizzo l'output raw.txt
mtrace
con:
mtrace a.out raw.txt
e ottieni:
Nessuna perdita di memoria.
C'è qualcosa che sto facendo di sbagliato o qualcosa che posso fare per consentire a mtrace
di trovare l'allocazione di memoria fortran che perde? Suppongo che gfortran stia usando una diversa chiamata malloc
, che mtrace
non traccia ...
In effetti, come ho scritto sopra ottengo lo stesso risultato se scrivo un main fortran che chiamerebbe (wrapped) mtrace ()
e muntrace ()
.
EDITED: ho preso in considerazione altre opzioni (incluse alcune non ancora menzionate qui), ma il codice effettivo in fase di debug viene eseguito su P6 / AIX, quindi Valgrind sarebbe " solo " scomodo (deve funzionare su una macchina diversa), mentre Forcheck sarebbe scomodo (deve funzionare su una macchina diversa) e costoso (~ 3k $). Attualmente mtrace sarebbe la soluzione migliore, se funzionasse.
MODIFICATO di nuovo: La mia ipotesi
Suppongo che gfortran stia usando una diversa chiamata
malloc
, chemtrace
non traccia ... ...
era corretto. Esaminando l'eseguibile (sia con nm
o readelf
) non c'è alcuna chiamata malloc ()
, ma _gfortran_allocate_array
quelli - che forse chiameranno malloc). Altre idee?
MODIFICATO di nuovo: Ho pubblicato la risposta ma non posso accettarla (vai a http: //stackoverflow.uservoice. com / pages / general / suggestions / 39426 e richiedi la funzione, è davvero necessaria - non è necessario guadagnare la reputazione)
Soluzione 3
Steve Kargl ha avuto la risposta, che brevemente è che mtrace non trova alcuna perdita, perché non c'è alcuna perdita se il compilatore è conforme allo standard: Vedi http://gcc.gnu.org/ml/fortran/2008-11/msg00163.html per i dettagli.
In realtà non sono un grande esperto di fortran (sono principalmente C / C ++ / java guy) e stavo anche usando un altro compilatore, che perde in una tale condizione (non ho detto che per mantenere la domanda più semplice). Quindi ho erroneamente pensato che la perdita fosse presente anche con gfortran, il che non è il caso (ho controllato con la parte superiore)
Altri suggerimenti
Non sono un esperto di mtrace, quindi non posso fare a meno. Suggerirei di provare lo strumento valgrind per trovare perdite di memoria se si utilizza un sistema supportato. Usare valgrind per trovare perdite di memoria è semplice come chiamare valgrind --leak-check = full ./a.out
.
Valgrind è solo Linux. Per un prodotto Windows, guarda Forcheck. http://www.forcheck.nl/features.htm
Ho esperienza con il debug dei programmi Fortran ma ad essere sincero non sono riuscito a capire davvero la tua domanda. Penso che sia perché non ho molta esperienza di debug in C / C ++ diversa da Fortran. Tuttavia, penso che questo ti gioverà:
L'uso del compilatore Intel con le seguenti opzioni di compilazione rileverà quasi ogni perdita di memoria, accesso errato all'indirizzo o utilizzo di puntatori / variabili non inizializzati durante il runtime.
Intel: -O0 -debug -traceback -check -ftrapuv
Anche per Gfortran è possibile ottenere praticamente tutti gli errori sopra descritti con queste opzioni del compilatore.
gfortran: -g -O0 -fbounds-check -Wuninitialized
Stampa il traceback delle chiamate della subroutine fino a quando si verifica l'errore. È sempre utile compilare con due diversi compilatori e nella mia esperienza non avrai quasi nessuna perdita di memoria dopo questo.