2008-11-03 19 views
5

我試圖用mtrace檢測Fortran程序中的內存泄漏。我正在使用gfortran編譯器。請參閱維基百科條目以獲取mtrace的(工作)C示例:我嘗試了兩種方法,即將mtrace()和muntrace()包裝在Fortran程序中並調用它們,並創建一個C程序直接調用mtrace()和muntrace(),除此之外的Fortran代碼泄漏。 這兩種方法都無法檢測到內存泄漏,但在這裏我僅僅介紹後者。命令mtrace的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(); 
} 

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 

我編譯:

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

gfortran -g example.c leaky.f90 

然後我跑0

然後我解析raw.txtmtrace輸出用:

mtrace a.out raw.txt 

,並得到:

沒有內存泄漏。

有什麼我做錯了,或者是我可以做的,讓mtrace找到漏水的FORTRAN內存分配?我猜gfortran正在使用不同的malloc調用,mtrace不跟蹤... 事實上,正如我上面寫的我得到同樣的結果,如果我寫一個FORTRAN主這將調用(包裝)mtrace()muntrace()

編輯:我認爲其他選項(包括一些尚未在此提及的),但實際正在調試的代碼在P6/AIX上運行,所以Valgrind會「不便」(它需要在不同的機器上運行),而Forcheck會很不方便(它需要在不同的機器上運行)和昂貴的(〜3k $)。目前mtrace是最好的解決方案,如果它工作的話。

再次編輯: 我猜

我猜gfortran正在使用不同的malloc調用,mtrace不跟蹤...

是正確的。展望可執行文件(或者與nmreadelf)沒有任何malloc()電話,但_gfortran_allocate_array的 - 這可能會調用malloc)。任何其他想法?

再次編輯: 我張貼的答案,但我不能接受它(去http://stackoverflow.uservoice.com/pages/general/suggestions/39426和要求的功能,它真正需要的 - 沒有信譽收穫希望)

回答

1

史蒂夫Kargl有了答案,這簡單是命令mtrace沒有找到任何泄漏,因爲沒有任何泄漏,如果編譯器符合標準:詳見http://gcc.gnu.org/ml/fortran/2008-11/msg00163.html。其實我並不是一個大的fortran專家(我主要是C/C++/java人),而且我還使用了另一個編譯器,它在這種情況下會泄漏(我沒有提到讓問題更容易)。因此,我錯誤地認爲泄漏也存在與gfortran,情況並非如此(我頂部檢查)

1

我不是命令mtrace的專家,所以我對此無能爲力。如果您使用的是支持的系統,我建議您嘗試使用valgrind工具來查找內存泄漏。使用valgrind查找內存泄漏與調用valgrind --leak-check=full ./a.out一樣簡單。

1

我有調試Fortran程序的經驗,但說實話,我真的不明白你的問題。我認爲這是因爲我沒有太多與Fortran不同的C/C++調試經驗。不過我認爲這將有利於你:

使用英特爾編譯器有以下的編譯選項將檢測幾乎所有的內存泄漏,錯誤地址的訪問或運行期間使用未初始化的指針/變量。

英特爾: -O0 -debug -traceback -check -ftrapuv

對於Gfortran還你幾乎可以得到任何與這些編譯器選項上述錯誤。

gfortran: -g -O0 -fbounds檢查-Wuninitialized

它將打印子程序調用回溯,直到發生錯誤。使用兩種不同的編譯器進行編譯總是很有幫助的,根據我的經驗,在此之後您幾乎不會有內存泄漏。