2008-11-03 10 views
5

Próbuję użyć mtrace do wykrywania wycieków pamięci w programie fortran. Używam kompilatora gfortran. Zobacz wpis wikipedia dla (pracy) C przykład mtrace: http://en.wikipedia.org/wiki/Mtracemtrace for a fortran program

Próbowałem na dwa sposoby, tj. Owijanie mtrace() i muntrace() i wywoływanie ich z programu fortran, jak również tworzenie programu C, który bezpośrednio wywołaj mtrace() i muntrace(), oprócz przeciekającego kodu fortranu pomiędzy. Oba podejścia nie wykryją przecieku pamięci, ale tutaj przedstawiam tylko te ostatnie.

przyklad.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 

skompilować z:

gfortran -g example.c leaky.f90 

Potem biegnę z:

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

Potem analizować dane wyjściowe raw.txtmtrace z:

mtrace a.out raw.txt 

a otrzymasz:

ma wycieków pamięci.

Czy jest coś, co robię źle, czy coś, co mogę zrobić, aby mtrace znaleźć nieszczelny przydział pamięci Fortran? Myślę, że gfortran używa innego wywołania malloc, którenie śledzi ... W rzeczywistości, jak napisałem powyżej, otrzymuję ten sam wynik, jeśli napiszę fortran main, który nazwałby (owinięty) mtrace() i muntrace().

EDYTOWANA: Rozważyłem inne opcje (w tym niektóre jeszcze nie wymienione tutaj), ale rzeczywisty debugowany kod działa na P6/AIX, więc Valgrind byłoby "po prostu" niewygodne (musi działać na innej maszynie), mając na uwadze, że Forcheck byłby niewygodny (musi działać na innej maszynie) i drogi (~ 3k $). W tej chwili mtrace byłby najlepszym rozwiązaniem, gdyby działało.

EDITED ponownie: Domyślam

Chyba gfortran używa innego malloc połączenia, które mtrace nie śledzi ...

była prawidłowa. Zaglądając do pliku wykonywalnego (albo z nm lub readelf), nie ma żadnych połączeń malloc(), ale może je wywoływać malloc). Jakieś inne pomysły?

EDITED ponownie: wysłałem odpowiedź, ale nie mogę zaakceptować go (przejdź do http://stackoverflow.uservoice.com/pages/general/suggestions/39426 i zwrócić się do funkcji, to jest naprawdę potrzebne - no gain reputacja chciał)

Odpowiedz

1

Steve Kargl miał odpowiedź, która w skrócie jest to, że mtrace nie znajdzie żadnego przecieku, ponieważ nie ma żadnego wycieku jeśli kompilator jest zgodny ze standardem: Zobacz http://gcc.gnu.org/ml/fortran/2008-11/msg00163.html szczegóły.

W rzeczywistości nie jestem wielkim ekspertem fortranowym (jestem w większości C/C++/facetem java), a także korzystałem z innego kompilatora, który WYJMUJE wyciek w takim stanie (nie wspomniałem o tym zadawaj pytania łatwiej). Pomyłkowo myślałem, że wyciek był tam również z gfortran, co nie jest prawdą (sprawdziłem z góry)

1

Nie jestem ekspertem od mtrace, więc nic na to nie poradzę. Proponuję wypróbować narzędzie valgrind, aby znaleźć wycieki pamięci, jeśli używasz obsługiwanego systemu. Używanie valgrind do znajdowania wycieków pamięci jest tak proste jak wywołanie valgrind --leak-check=full ./a.out.

1

Mam doświadczenie w debugowaniu programów Fortran, ale szczerze mówiąc, nie mogłem zrozumieć twojego pytania. Myślę, że to dlatego, że nie mam wiele doświadczeń debugowania C/C++, które różnią się od Fortran. Niemniej jednak myślę, że to ci się przyda:

Użycie kompilatora Intel z następującymi opcjami kompilacji wykrywa prawie każdy wyciek pamięci, niepoprawny dostęp do adresu lub używa niezainicjowanego wskaźnika/zmiennej podczas wykonywania.

Intel: -O0 -debug -traceback -Check -ftrapuv

Dla gfortran również można bardzo dużo któryś z powyższych błędów z tych opcji kompilatora.

gfortran: -g -O0 -fbounds sprawdzić -Wuninitialized

To będzie wydrukować traceback podprogramu wzywa do momentu, w którym wystąpił błąd. Zawsze pomocna jest kompilacja z dwoma różnymi kompilatorami i według mojego doświadczenia po tym nie będzie prawie żadnego wycieku pamięci.