Я пытаюсь использовать mtrace для обнаружения утечек памяти в программе fortran. Я использую компилятор gfortran. См. Запись в википедии для (рабочего) примера mtrace на C: http://en.wikipedia.org/wiki/Mtrace
Я попробовал оба способа, то есть обернул mtrace () и muntrace () и вызвал их из программы fortran, а также создал программу C, которая напрямую вызывает mtrace () и muntrace (), помимо утечки кода fortran между ними. Оба подхода не позволяют обнаружить утечку памяти, но здесь я представляю только последнее.
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();
}
утечка.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
Я компилирую:
gfortran -g example.c leaky.f90
Затем я бегу с:
export MALLOC_TRACE=`pwd`/raw.txt; ./a.out
Затем я анализирую вывод raw.txtmtrace с помощью:
mtrace a.out raw.txt
и получить:
Никаких утечек памяти.
Что я делаю неправильно, или что-то я могу сделать, чтобы mtrace нашел утечку в распределении памяти fortran? Я предполагаю, что gfortran использует другой вызов malloc, который mtrace не отслеживает ...
Фактически, как я уже писал выше, я получаю тот же результат, если напишу fortran main, который будет вызывать (завернутые) mtrace() и muntrace().
EDITED: я рассмотрел другие варианты (в том числе некоторые, еще не упомянутые здесь), но фактический отлаживаемый код работает на P6 / AIX, поэтому Valgrind будет "просто" неудобно (он должен работать на другой машине), тогда как Forcheck будет неудобно (нужно запускать на другой машине) и дорого (~ 3k $). На данный момент лучшим решением была бы mtrace, если бы она работала.
ИЗМЕНИТЬ снова: Моя догадка
I guess gfortran is using a different
malloccall, whichmtracedoes not trace...
было правильно. Заглянув в исполняемый файл (либо с nm, либо с readelf), нет никакого вызова malloc(), но есть вызовы _gfortran_allocate_array - которые, возможно, вызовут malloc). Есть другие идеи?
ИЗМЕНИТЬ снова: Я опубликовал ответ, но не могу его принять (перейдите к http://stackoverflow.uservoice.com/pages/general/suggestions/39426 и запросите функцию, она действительно нужна - никакого повышения репутации не требуется)





Я не эксперт по mtrace, поэтому ничего не могу поделать. Я бы посоветовал вам попробовать инструмент Valgrind для поиска утечек памяти, если вы используете поддерживаемую систему. Использовать valgrind для поиска утечек памяти так же просто, как вызвать valgrind --leak-check=full ./a.out.
Valgrind - это только Linux. Для продукта Windows посмотрите Forcheck. http://www.forcheck.nl/features.htm
У Стива Каргла был ответ, который вкратце заключается в том, что mtrace не обнаруживает утечек, потому что утечки не происходит, если компилятор соответствует стандарту: подробности см. В http://gcc.gnu.org/ml/fortran/2008-11/msg00163.html.
На самом деле я не большой эксперт по фортрану (я в основном парень C / C++ / java), и я также использовал другой компилятор, который ДЕЙСТВИТЕЛЬНО утекает в таком состоянии (я не упоминал об этом, чтобы упростить вопрос ). Таким образом я ошибочно подумал, что утечка была также с гфортраном, что не так (я проверял с верхом)
У меня есть опыт отладки программ Fortran, но, честно говоря, я не мог понять ваш вопрос. Я думаю, это потому, что у меня не так много опыта отладки C / C++, который отличается от Fortran. Тем не менее я думаю, что это принесет вам пользу:
Использование компилятора Intel со следующими параметрами компиляции позволит обнаружить практически любую утечку памяти, неправильный адресный доступ или использование неинициализированного указателя / переменной во время выполнения.
интел: -O0 -debug -traceback -check -ftrapuv
Для Gfortran вы также можете получить любую из вышеперечисленных ошибок с этими параметрами компилятора.
Гфортран: -g -O0 -fbounds-check -Wuninitialized
Он будет печатать обратную трассировку вызовов подпрограмм до тех пор, пока не возникнет ошибка. Всегда полезно компилировать с двумя разными компиляторами, и по моему опыту у вас почти не будет утечки памяти после этого.