2008-11-03 11 views
5

J'essaie d'utiliser mtrace pour détecter les fuites de mémoire dans un programme Fortran. J'utilise le compilateur gfortran. Voir l'entrée wikipedia pour un (travail) C exemple de mtrace: http://en.wikipedia.org/wiki/Mtracemtrace pour un programme fortran

j'ai essayé les deux sens, à savoir envelopper la mtrace() et muntrace() et les appeler à partir du programme Fortran, ainsi que de créer un programme C qui appelez directement le mtrace() et muntrace(), en plus du code fortran qui fuit entre les deux. Les deux approches ne parviendront pas à détecter la fuite de mémoire, mais ici, je présente uniquement ce dernier.

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 

Je compilez avec:

gfortran -g example.c leaky.f90 

Alors je cours avec:

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

Je Parse la sortie raw.txtmtrace avec:

mtrace a.out raw.txt 

et obtenez:

Aucune fuite de mémoire.

Y at-il quelque chose que je fais mal, ou quelque chose que je peux faire pour laisser mtrace trouver l'allocation de mémoire Fortran qui fuit? Je suppose que gfortran utilise un appel malloc différent, qui mtrace ne trace pas ... En fait, comme je l'ai écrit ci-dessus, je reçois le même résultat si j'écris un fortran principal qui appellerait le (emballé) mtrace() et muntrace(). EDITED: J'ai considéré d'autres options (dont certaines non encore mentionnées ici), mais le code en cours de débogage fonctionne sur P6/AIX, donc Valgrind serait "juste" incommode (il doit fonctionner sur une machine différente), alors que Forcheck serait gênant (il doit fonctionner sur une machine différente) et coûteux (~ 3k $). À l'heure actuelle, mtrace serait la meilleure solution, si cela fonctionnait.

à nouveau sous la direction: Je pense

Je suppose que gfortran utilise un appel malloc différent, qui ne trace pas mtrace ...

était correcte. En regardant dans l'exécutable (soit avec nm ou readelf) il n'y a pas d'appel malloc(), mais _gfortran_allocate_array - qui appellera peut-être malloc). D'autres idées?

ÉDITÉE à nouveau: J'ai posté la réponse, mais je ne peux pas l'accepter (aller à http://stackoverflow.uservoice.com/pages/general/suggestions/39426 et demander la fonction, il est vraiment nécessaire - aucun gain de réputation voulu)

Répondre

1

Steve Kargl avait la réponse, qui est brièvement que mtrace ne trouve pas de fuite, car il n'y a pas de fuite si le compilateur est conforme à la norme: Voir http://gcc.gnu.org/ml/fortran/2008-11/msg00163.html pour plus de détails. En fait, je ne suis pas un grand expert en fortran (je suis surtout en C/C++/java guy), et j'utilisais aussi un autre compilateur, qui fuit dans une telle condition (je ne le mentionne pas pour Gardez la question plus facile). J'ai donc pensé à tort que la fuite était là aussi avec gfortran, ce qui n'est pas le cas (j'ai vérifié par dessus)

1

Je ne suis pas un expert en mtrace, donc je ne peut pas aider avec ça. Je suggère que vous essayez l'outil valgrind pour trouver des fuites de mémoire si vous utilisez un système pris en charge. Utiliser valgrind pour trouver des fuites de mémoire est aussi simple qu'appeler valgrind --leak-check=full ./a.out.

1

J'ai de l'expérience avec les programmes Fortran de débogage mais pour être honnête je n'ai pas vraiment compris votre question. Je pense que c'est parce que je n'ai pas beaucoup d'expérience en débogage C/C++ qui est différente de Fortran. Néanmoins, je pense que cela va vous profiter:

L'utilisation du compilateur Intel avec les options de compilation suivantes détectera presque toute fuite de mémoire, mauvais accès d'adresse ou utilisant un pointeur/variable non initialisé pendant l'exécution.

intel: -O0 debug -traceback -check -ftrapuv

Pour gfortran aussi vous pouvez obtenir à peu près toutes les erreurs ci-dessus avec ces options de compilateur.

gfortran: -g -O0 -fbounds vérifier -Wuninitialized

Il imprime le retraçage du sous-programme appelle jusqu'à ce que lorsque l'erreur se produit. Il est toujours utile de compiler avec deux compilateurs différents et, d'après mon expérience, il n'y aura presque plus de fuite de mémoire après cela.

Questions connexes