【问题标题】:mtrace for a fortran program用于 fortran 程序的 mtrace
【发布时间】:2010-09-20 14:03:07
【问题描述】:

我正在尝试使用mtrace 来检测fortran 程序中的内存泄漏。我正在使用 gfortran 编译器。有关 mtrace 的(工作)C 示例,请参阅维基百科条目:http://en.wikipedia.org/wiki/Mtrace

我尝试了两种方法,即包装 mtrace() 和 muntrace() 并从 fortran 程序中调用它们,以及创建一个直接调用 mtrace() 和 muntrace() 的 C 程序,除了泄漏的 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

我编译:

gfortran -g example.c leaky.f90

然后我运行:

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

然后我解析raw.txt mtrace 输出:

mtrace a.out raw.txt

然后得到:

没有内存泄漏。

我做错了什么,或者我可以做些什么让mtrace 找到泄漏的fortran 内存分配?我猜 gfortran 正在使用不同的malloc 调用,mtrace 没有跟踪... 事实上,正如我在上面所写的,如果我编写一个调用(包装的)mtrace()muntrace() 的 fortran 主程序,我会得到相同的结果。

已编辑:我考虑了其他选项(包括此处尚未提及的一些选项),但正在调试的实际代码在 P6/AIX 上运行,因此 Valgrind 将“只是”不方便(它需要在不同的机器上运行),而Forcheck 会很不方便(它需要在不同的机器上运行)并且价格昂贵(~ 3k$)。如果可行的话,目前 mtrace 将是最好的解决方案。

再次编辑: 我的猜测

我猜 gfortran 正在使用不同的 malloc 调用,mtrace 没有跟踪...

是正确的。查看可执行文件(使用nmreadelf)没有任何malloc() 调用,但_gfortran_allocate_array 调用-可能会调用malloc)。还有其他想法吗?

再次编辑: 我发布了答案,但我无法接受(转至 http://stackoverflow.uservoice.com/pages/general/suggestions/39426 并请求该功能,它真的很需要 - 不希望获得声誉)

【问题讨论】:

    标签: c gcc memory-leaks fortran mtrace


    【解决方案1】:

    我不是 mtrace 方面的专家,所以对此我无能为力。如果您使用受支持的系统,我建议您尝试使用valgrind 工具来查找内存泄漏。使用 valgrind 查找内存泄漏就像调用 valgrind --leak-check=full ./a.out 一样简单。

    【讨论】:

      【解决方案2】:

      Valgrind 仅适用于 Linux。对于 Windows 产品,请查看 Forcheck。 http://www.forcheck.nl/features.htm

      【讨论】:

        【解决方案3】:

        Steve Kargl 给出了答案,简单来说,mtrace 没有发现任何泄漏,因为如果编译器符合标准,则不会有任何泄漏:有关详细信息,请参阅 http://gcc.gnu.org/ml/fortran/2008-11/msg00163.html

        事实上,我不是一个大的 fortran 专家(我主要是 C/C++/java 人),而且我还在使用另一个编译器,它在这种情况下确实会泄漏(我没有提到要保留这个问题更容易)。因此我错误地认为 gfortran 也存在泄漏,事实并非如此(我检查了 top)

        【讨论】:

          【解决方案4】:

          我有调试 Fortran 程序的经验,但老实说,我无法真正理解您的问题。我认为这是因为我没有太多与 Fortran 不同的 C/C++ 调试经验。不过,我认为这会对您有所帮助:

          使用带有以下编译选项的英特尔编译器将检测到几乎所有内存泄漏、错误地址访问或在运行时使用未初始化的指针/变量。

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

          对于 Gfortran,您几乎可以使用这些编译器选项获得上述任何错误。

          gfortran: -g -O0 -fbounds-check -Wuninitialized

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-10-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-04-22
            • 1970-01-01
            • 2011-10-20
            • 2020-01-03
            相关资源
            最近更新 更多