一个fortran程序的mtrace

一个fortran程序的mtrace,c,gcc,memory-leaks,fortran,mtrace,C,Gcc,Memory Leaks,Fortran,Mtrace,我试图使用mtrace检测fortran程序中的内存泄漏。我正在使用gfortran编译器。请参阅wikipedia条目,了解mtrace的(工作)C示例: 我尝试了两种方法,即包装mtrace()和muntrace(),并从fortran程序中调用它们,以及创建一个C程序,直接调用mtrace()和muntrace(),除了中间泄漏的fortran代码。 这两种方法都无法检测内存泄漏,但这里我只介绍后者 例c #include <stdlib.h> #include <mch

我试图使用
mtrace
检测fortran程序中的内存泄漏。我正在使用gfortran编译器。请参阅wikipedia条目,了解mtrace的(工作)C示例:

我尝试了两种方法,即包装mtrace()和muntrace(),并从fortran程序中调用它们,以及创建一个C程序,直接调用mtrace()和muntrace(),除了中间泄漏的fortran代码。 这两种方法都无法检测内存泄漏,但这里我只介绍后者

例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();
}
我编译时使用:

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
不会跟踪。。。 事实上,正如我在上面所写的,如果我编写一个fortran main,调用(wrapped)
mtrace()
muntrace()
,我会得到相同的结果

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

再次编辑: 我猜

我猜gfortran使用的是另一个
malloc
调用,
mtrace
不会跟踪

这是正确的。查看可执行文件(使用
nm
readelf
)时,没有任何
malloc()
调用,而是
\u gfortran\u allocate\u array
调用-可能会调用malloc)。还有其他想法吗

再次编辑:
我发布了答案,但我无法接受(请访问并请求该功能,它确实是必需的-不需要获得声誉)

我不是mtrace方面的专家,因此我无法帮助。如果您使用的是受支持的系统,我建议您尝试使用该工具查找内存泄漏。使用valgrind查找内存泄漏非常简单,只需调用
valgrind--leak check=full./a.out

valgrind仅适用于Linux。有关windows产品,请查看Forcheck。
Steve Kargl得到了答案,简单地说,mtrace没有发现任何泄漏,因为如果编译器符合标准,就不会有任何泄漏:有关详细信息,请参阅


事实上,我不是一个大型fortran专家(我主要是C/C++/java专家),我还使用了另一个编译器,在这种情况下确实会泄漏(我没有提到这一点是为了让问题更简单)。因此,我错误地认为gfortran也存在漏洞,事实并非如此(我与top进行了检查)

我有调试Fortran程序的经验,但老实说,我无法真正理解您的问题。我想这是因为我没有太多与Fortran不同的C/C++调试经验。尽管如此,我认为这将使您受益:

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

英特尔: -O0-调试-回溯-检查-ftrapuv

对于Gfortran,您也可以通过这些编译器选项获得上述任何错误

格弗特兰: -g-O0-fbounds检查-Wuninitialized

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

mtrace a.out raw.txt