Fortran 程序的 mtrace

发布于 2024-07-07 23:51:50 字数 2374 浏览 10 评论 0原文

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

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

example.cleaky.f90

#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();
}

我用以下内容

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 不会跟踪... 事实上,正如我上面所写,如果我编写一个 fortran main 来调用(包装的)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 并请求该功能,它确实需要 - 不需要获得声誉)

I'm trying to use mtrace to detect memory leaks in a fortran program. I'm using the gfortran compiler. See the wikipedia entry for a (working) C example of mtrace: http://en.wikipedia.org/wiki/Mtrace

I tried both ways, i.e. wrapping the mtrace() and muntrace() and call them from the fortran program, as well as create a C program which directly call the mtrace() and muntrace(), besides the leaking fortran code in between.
Both approaches will fail to detect the memory leak, but here I'm presenting only the latter.

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

I compile with:

gfortran -g example.c leaky.f90

Then I run with:

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

Then I parse the raw.txt mtrace output with:

mtrace a.out raw.txt

and get:

No memory leaks.

Is there anything I'm doing wrong, or something I can do to let mtrace find the leaky fortran memory allocation? I guess gfortran is using a different malloc call, which mtrace does not trace...
In fact, as I wrote above I get the same result if I write a fortran main which would call the (wrapped) mtrace() and muntrace().

EDITED: I considered other options (including some not yet mentioned here), but the actual code being debugged runs on P6/AIX, so Valgrind would be "just" inconvenient (it needs to run on a different machine), whereas Forcheck would be inconvenient (it needs to run on a different machine) and expensive ( ~ 3k$). At present mtrace would be the best solution, if it worked.

EDITED again:
My guess

I guess gfortran is using a different malloc call, which mtrace does not trace...

was correct. Looking into the executable (either with nm or readelf) there isn't any malloc() call, but _gfortran_allocate_array ones - which maybe will call malloc). Any other ideas?

EDITED again:
I posted the answer but I cannot accept it (go to http://stackoverflow.uservoice.com/pages/general/suggestions/39426 and request the feature, it's really needed - no reputation gain wanted)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

饭团 2024-07-14 23:51:50

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

I'm not an expert on mtrace, so I can't help with that. I would suggest that you try the valgrind tool to find memory-leaks if you are using a supported system. Using valgrind for finding memory-leaks is as simple as calling valgrind --leak-check=full ./a.out.

宁愿没拥抱 2024-07-14 23:51:50

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

Valgrind is Linux only. For a windows product look at Forcheck.
http://www.forcheck.nl/features.htm

命硬 2024-07-14 23:51:50

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

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

Steve Kargl had the answer, which briefly is that mtrace does not find any leak, because there isn't any leak if the compiler conforms to the standard: See http://gcc.gnu.org/ml/fortran/2008-11/msg00163.html for details.

In fact I'm not a big fortran expert (I'm mostly C/C++/java guy), and I was also using another compiler, which DOES leak in such a condition (I didn't mention that to keep the question easier). Thus I mistakenly thought that the leak was there also with gfortran, which is not the case (I checked with top)

寄与心 2024-07-14 23:51:50

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

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

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

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

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

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

I have experience with debugging Fortran programs but to be honest I could not really understand your question. I think it is because I do not have much of C/C++ debugging experience which different to Fortran. Nevertheless I think this will benefit you:

Using the Intel compiler with the following compile options will detect almost any memory leak , wrong address access or using uninitialized pointer/variable during runtime.

intel:
-O0 -debug -traceback -check -ftrapuv

For Gfortran also you can pretty much get any of the above errors with these compiler options.

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

It will print the traceback of subroutine calls until where the error occurs. It is always helpful to compile with two different compilers and in my experience you will have almost no memory leak after this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文