一个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