C/C++ でメモリ関連のバグを調べるには? [C/C++]

C/C++ でメモリ関連のバグを調べるには、Valgrind が使用できそうだ。

Valgrind はメモリとスレッドに関するバグを検出するデバッガである。Valgrind Home では、

Valgrind is an award-winning instrumentation framework for building dynamic analysis tools. There are Valgrind tools that can automatically detect many memory management and threading bugs, and profile your programs in detail. You can also use Valgrind to build new tools. 

と紹介されている。 私はメモリに関するバグを調べたくて使ったことはあるが、スレッド関連のバグを調べるために使用したと経験は今のところ無い。

Valgrind の仕組みは Valgrind によると次のようになっているらしい。

Your program is then run on a synthetic CPU provided by the Valgrind core. As new code is executed for the first time, the core hands the code to the selected tool. The tool adds its own instrumentation code to this and hands the result back to the core, which coordinates the continued execution of this instrumented code.

つまり、デバッグされるプログラムは Valgrind が提供する仮想的な CPU 上で動作すると言うことかな?

※以下、古い話なので、最新の Valgrind には該当しない場合がある。

@@ unlikely looking definition in unparsed remains ";"

と出力されるときは、Valgrind を コンパイルした g++ のバージョンと Valgrind に実行させるプログラムをコンパイルした g++ のバージョンが異なる可能性がある。というか、私はそれにはまった過去が...。どちらも g++ は3.3.0 以上を用いた方が良いと思う。

と書いたが、 に2004-09-30 13:06 時点の reply で

    Those errors can safely be ignored - they are fixed in the CVS code.

だそうな。Valgrind の ver. は 2.2.0。 詳しくは、該当スレッド参照。


==19482== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 1)
==19482== malloc/free: in use at exit: 1280 bytes in 1 blocks.
==19482== malloc/free: 1 allocs, 0 frees, 1280 bytes allocated.
==19482== For counts of detected errors, rerun with: -v
==19482== searching for pointers to 1 not-freed blocks.
==19482== checked 1873888 bytes.
==19482== LEAK SUMMARY:
==19482==    definitely lost: 0 bytes in 0 blocks.
==19482==    possibly lost:   0 bytes in 0 blocks.
==19482==    still reachable: 1280 bytes in 1 blocks.
==19482==         suppressed: 0 bytes in 0 blocks.
==19482== Reachable blocks (those to which a pointer was found) are not shown.
==19482== To see them, rerun with: --show-reachable=yes

と alloc に対して free が一致しないことがある。これは g++ 2.9.5 の場合は g++ に -D__USE_MALLOC オプションをつけて試すと良いらしい。ここら辺も、古い話。最新を追いかけていないので、もしかすると修正されているかもしれない。

※以上、古い話おしまい。最新の Valgrind には該当しないかもしれない。

Valdgind はもともと で公開されていたんだけど、 に移動したらしい。