2008-11-03 71 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

它将打印子程序调用回溯,直到发生错误。使用两种不同的编译器进行编译总是很有帮助的,根据我的经验,在此之后您几乎不会有内存泄漏。