fortranプログラムのmtrace
-
06-07-2019 - |
質問
Fortranプログラムでメモリリークを検出するために mtrace
を使用しようとしています。私はgfortranコンパイラを使用しています。 mtraceの(動作する)Cの例については、ウィキペディアのエントリを参照してください: http://en.wikipedia.org/ wiki / Mtrace
mtrace()とmuntrace()をラッピングしてfortranプログラムから呼び出し、mtran()とmuntrace()を直接呼び出すCプログラムを作成します。間に。 どちらの方法もメモリリークの検出に失敗しますが、ここでは後者のみを示します。
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
and get:
メモリリークなし。
間違っていることはありますか、または mtrace
が漏れやすいFortranメモリ割り当てを見つけるためにできることはありますか? gfortranは別の malloc
呼び出しを使用していると思いますが、 mtrace
はトレースしません...
実際、上で書いたように、(ラップされた) mtrace()
と muntrace()
を呼び出すfortran mainを書いても同じ結果になります。
編集済み:他のオプション(まだここで言及されていないものも含む)を検討しましたが、デバッグ中の実際のコードはP6 / AIXで実行されるため、Valgrindは「ただ」でした。 Forcheckは不便(別のマシンで実行する必要がある)で、高価(〜3k $)ですが、不便です(別のマシンで実行する必要があります)。現時点では、mtraceが最適なソリューションです。
再び編集: 私の推測
gfortranは別の
malloc
呼び出しを使用していると思いますが、mtrace
はトレースしません...
は正しかった。実行可能ファイル( nm
または readelf
のいずれか)を調べると、 malloc()
呼び出しはありませんが、 _gfortran_allocate_array
ones-多分mallocを呼び出します)。他のアイデアはありますか?
再び編集: 回答を投稿しましたが、受け入れられません( http://stackoverflow.uservoiceにアクセスしてください。 com / pages / general / suggestions / 39426 を選択して機能をリクエストします。本当に必要です。評判の向上は望んでいません)
解決 3
Steve Karglが答えました。簡単に言えば、コンパイラが標準に準拠している場合はリークがないため、mtraceはリークを検出しません。詳細についてはhttp://gcc.gnu.org/ml/fortran/2008-11/msg00163.html 。
実際、私は大きなFortranエキスパートではありません(私は主にC / C ++ / javaの人です)、また、そのような状態でリークする別のコンパイラを使用していました(私はそれを維持することは言及しませんでした)質問は簡単です)。したがって、gfortranでもリークが存在すると誤って考えていましたが、そうではありません(topで確認しました)
他のヒント
私はmtraceの専門家ではないので、それを手伝うことはできません。サポートされているシステムを使用している場合は、 valgrind ツールを使用してメモリリークを見つけることをお勧めします。 valgrindを使用してメモリリークを見つけるのは、 valgrind --leak-check = full ./a.out
を呼び出すのと同じくらい簡単です。
ValgrindはLinuxのみです。 Windows製品については、Forcheckをご覧ください。 http://www.forcheck.nl/features.htm
Fortranプログラムのデバッグの経験はありますが、正直なところ、あなたの質問を本当に理解できませんでした。 Fortranとは異なるC / C ++デバッグの経験があまりないためだと思います。それでも、これはあなたに利益をもたらすと思います:
次のコンパイルオプションでIntelコンパイラを使用すると、実行中にほとんどすべてのメモリリーク、誤ったアドレスアクセス、または初期化されていないポインタ/変数の使用が検出されます。
インテル: -O0 -debug -traceback -check -ftrapuv
Gfortranの場合、これらのコンパイラオプションを使用すると、上記のエラーのほとんどを取得できます。
gfortran: -g -O0 -fbounds-check -Wuninitialized
エラーが発生するまで、サブルーチン呼び出しのトレースバックを出力します。 2つの異なるコンパイラを使用してコンパイルすることは常に役立ちます。私の経験では、この後メモリリークはほとんどありません。