はじめに
Valgrindツール群はプログラムの品質向上を支援するデバッグ/分析ツールを提供します。
それらツールのうち最も有名なものは「Memcheck」と呼ばれています。
MemcheckはC/C++で共通する、クラッシュ、想定外の動作に至る多数のメモリー関連エラーを検出出来ます。
本ドキュメントでは以後、Memcheckを用いてプログラムのメモリーエラーを検出するために必要となる最低限の情報を提示します。
Memcheckと他ツールの全解説はUser Manualを参照して下さい。
プログラムの準備
コンパイルの際、-gオプションを指定しデバッグ情報を付加することでMemcheckのエラーメッセージに行数を含めることが出来ます。
実行速度低下が問題にならないのであれば、-O0オプションを指定することでより正確な情報が得られます。
一般的にMemcheckは-O1を指定してコンパイルしたコードをかなり正確かつ-O0より高速に動作させますが、エラーメッセージに含まれる行数が不正確たりえることは念頭においてください。
ーO2以上の最適化オプションの使用は、実際には存在しない未初期化変数エラーを計上することがあるため推奨できません。
Memcheck上でプログラムを実行する
あなたが実行したいプログラムは以下のようなものとすると
myprog arg1 arg2
下記のように実行します
valgrind --leak-check=yes myprog arg1 arg2
Memcheckはデフォルトで動作するツールです。「--leak-check」オプションはメモリーリーク検査精度を変更します。
プログラムの実行速度は通常より遅くなるでしょう。(大体20〜30倍程度)
Memcheckは発見したメモリーエラー,リークについてメッセージを出力します。
Memcheckの出力メッセージの解説
example.cというファイル名のメモリーエラーとメモリーリークを含むサンプルプログラムを用意します。
#include <stdlib.h>
void f(void)
{
int * x = malloc(10 * sizeof(int));
x[10] = 0; // problem 1: heap block overrun
} // problem 2: memory leak -- x not freed
int main(void)
{
f();
return 0;
}
ほとんどのオーバーラン(problem1)エラーメッセージは以下のように出力されます。
==19182== Invalid write of size 4
==19182== at 0x804838F: f (example.c:6)
==19182== by 0x80483AB: main (example.c:11)
==19182== Address 0x1BA45050 is 0 bytes after a block of size 40 alloc'd
==19182== at 0x1B8FF5CD: malloc (vg_replace_malloc.c:130)
==19182== by 0x8048385: f (example.c:5)
==19182== by 0x80483AB: main (example.c:11)
各項目について
- エラーメッセージが多数出力されます。注意深く読んで下さい。
- 19182はプロセスIDです。大抵の場合、重要な要素ではありません。
- 最初の行("Invalid write...")はエラーの種類を示しています。ここではオーバーランのせいで、書きこむべきでないメモリに書き込んでいます。
- 最初の行以降には問題発生箇所を示すスタックトレースが並びます。スタックトレースは特にC++STLを使用している場合大量に得られ、解析しにくいでしょう。&br;ボトムアップ式に読むことは有益です。もしスタックトレースをが十分でなかった場合は、--num-callersオプションを使用して行数を増やしてください。
- コードアドレス(例:0x804838F)は大抵の場合、重要な要素ではありませんが、時折変なバグで決定的な解析要素となります。
- いくつかのエラーメッセージではメモリーアドレスに続けて別要素を含んでいます。&br;このうちの1つではexample.c5行目にてmalloc()で確保されたメモリーの終端を通過して書きこまれたことを示しています。
あるエラーは別のエラーに起因して引き起こされることがあるため、報告に従いエラーを修正する価値があります。
Memcheckでそういったことを行うのは困難です。
最終更新:2011年04月29日 01:45