1. ホーム
  2. リナックス

Linuxでvalgrindを使ってメモリリークをチェックする

2022-02-27 18:47:50

Valgrindのインストール

1. www.valgrind.org下载最新版valgrind-3.2.3.tar.bz2 にアクセスします。

2. インストールパッケージを解凍します: tar -jxvf valgrind-3.2.3.tar.bz2

3. 解凍して、valgrind-3.2.3 というディレクトリを生成します。

4. cd valgrind-3.2.3

5. 5.実行. /autogen.sh を実行して環境を設定する(標準の autoconf ツールが必要)(オプション)。

6. . /configure; Valgrind が MakeFile ファイルを生成するように設定します。詳細なパラメータ情報は INSTALL ファイルを参照してください。一般的には --prefix=/where/you/want/it/installed を設定すればよいでしょう。

7. Make; Valgrindをコンパイルする

8. make install; Valgrind をインストールします。

Valgrind付属ツール

Valgrind は memcheck, addrcheck, cachegrind, Massif, helgrind, Callgrind といった多くのツールをサポートしています。Valgrind を実行するとき、どのツールを使うか指定する必要があります。ツール名を省略すると、memcheck がデフォルトで実行されます。

1. memcheck

memcheck は、アプリケーションのメモリ管理に関する問題を検出します。メモリに対するすべての読み取り/書き込み操作をチェックし、すべての malloc/new/free/delete 呼び出しを傍受します。このため、memcheck ツールは、以下のような問題を検出することができます。

1) 未初期化メモリの使用

2) 既に解放されたメモリの読み書きをする場合

3)範囲外のメモリの読み出し/書き込み

4)不適切なメモリスタック空間の読み書き

5) メモリリーク

6) malloc/new/new[]とfree/delete/delete[]の使い方が一致しない。

7) srcとdstの重なり

2. キャッシュグラインド

cachegrind はキャッシュプロファイラです。CPU の L1、D1、L2 キャッシュの実行をシミュレートするので、コード中のキャッシュミスをピンポイントで検出することができます。必要なら、キャッシュミスの数、メモリ参照、キャッシュミスが発生したコード の各行、各関数、各モジュール、プログラム全体の概要を出力することができま す。より詳細な情報が必要な場合は、機械語コード1行あたりのミス回数を出力することができます。x86 と amd64 では、cachegrind は CPUID によってマシンのキャッシュ構成を自動的に検出するため、ほとんどの場合、それ以上の構成情報は必要ありません。

3. ヘルグラインド

helgrind はマルチスレッドプログラムで競合するデータを探します。 helgrind は複数のスレッドによってアクセスされ、一貫したロックを使用していないメモリアドレスを探します。これは、これらのアドレスが複数のスレッド間でアクセスされたときに同期されていないことを示し、見つけにくいタイミングの問題を引き起こす可能性が高いです。

Helgrindは、一貫したロックをせずに複数のスレッドによってアクセスされるメモリ領域を探します。この領域は、スレッド間の同期が失われ、見つけにくいエラーにつながることがよくあります。 " 競合検出アルゴリズムをさらに改善し、エラーの報告数を減少させました。

4. コールグラインド

Callgrind は実行時のデータ、関数呼び出しの関係、その他の情報を収集し、オプションでキャッ シュシミュレーションを実行することができる。callgrind_annotate はこのファイルの内容を可読形式に変換する.

一般的な使い方

$valgrind --tool=callgrind . /sec_infod

は、カレントディレクトリにcallgrind.out.[pid]を生成し、プログラムを終了したい場合は

$killall callgrind

次に

$callgrind_annotate --auto=yes callgrind.out.[pid] > log

$vi ログ

5.山塊

スタックパーサーは、プログラムがスタックでどれだけのメモリを使用しているかを測定し、ヒープブロック、ヒープ管理ブロック、スタックのサイズを教えてくれます。massif はメモリ使用量を減らすのに役立ち、仮想メモリを持つ最新のシステムでは、プログラムを高速化し、スワップ領域に留まる可能性を減らすこともできます。

6. ラッキー

lackeyは、独自のツールを作成するためのテンプレートとして使用できるサンプルプログラムです。プログラムの最後には、プログラムの実行に関する基本的な統計情報をプリントアウトします。

Valgrind用パラメータ

使用法: valgrind [オプション] prog-and-args [オプション]: すべての Valgrind ツールに共通のオプション

-tool=<名前>

最もよく使われるオプションです。valgrindのtoolnameという名前のツールを実行します。デフォルトはmemcheckです。

-h --help

カーネルと選択されたツールの両方を含む、すべてのオプションのヘルプを表示します。

--バージョン

valgrind カーネルのバージョンを表示します。各ツールはそれぞれ独自のバージョンを持っています。

-q --quiet

エラーメッセージのみを表示し、静かに実行します。

--冗長

より詳細な情報を表示します。

-trace-children=<yes|no>

子スレッドをトレースするか?[デフォルト:ノー]

--track-fds=<yes|no>

オープンファイルの記述を追跡するか?[デフォルト:なし]

--time-stamp=<yes|no>

LOGメッセージにタイムスタンプを追加しますか?[デフォルト:なし]

--log-fd=<number>

LOGを記述ファイル[2=stderr]に出力する。

-log-file=<ファイル>

実行中のプログラムのIDであるファイルfilename.PIDに出力を書き込む

--log-file-exactly=<file>

LOGメッセージをファイルに出力する

LOGメッセージの出力

--xml=yes

xml形式で情報を出力、memcheckのみ利用可

--num-callers=<number>

スタックトレースで呼び出し元を表示する[12]。

--error-exitcode=<number>

エラーが発生した場合、エラーコードを返す [0=無効] 。

--db-attach=<yes|no>

エラーが発生したとき、valgrindは自動的にデバッガgdbを起動します[default: no] 。

--db-command=<command>

デバッガを起動するコマンドラインオプション [gdb -nw %f %p]。

Memcheck ツールに適用される関連オプションです。

--leak-check=<no|summary|full>

リークに関する詳細な情報が必要ですか?リークとは、参照されていない、あるいは解放されていないメモリ空間の断片があることを意味します。summaryの場合、mallocの数、freeの数などの概要情報しか得られません。fullの場合、すべてのリーク、つまり、あるmalloc/freeの場所を特定する情報を出力します。[デフォルトはsummary]。

--show-reachable=<yes|no>

noの場合、参照されていないメモリリーク、またはmallocによって返されたメモリブロックの途中のどこかを指しているリークのみを出力します[デフォルト: no](訳注: 「リーク」)。

より詳細なパラメータディレクティブについては、付録Aを参照してください。

Valgrindの使用

まず、プログラムをコンパイルする際に、デバッグモード(gccコンパイラの-gオプション)をオンにします。デバッグ情報がなければ、どんなに優れた valgrind ツールでも、あるコードがどの関数に属しているのかを推測することはできません。デバッグオプションをオンにしてコンパイルし、valgrindでチェックすると、valgrindはコードのどの行がメモリリークしているかなど、詳細なレポートを与えてくれます。

C++プログラムをチェックする際に考慮すべきもう一つのオプションは、-fno-inlineです。これは、関数呼び出しのチェーンを明確にし、大規模なC++プログラムをナビゲートする際の混乱を軽減するものです。例えば、このオプションを使用すると、memcheck で openoffice をチェックするのが簡単になります。もちろん、この作業をしないかもしれませんが、このオプションを使うことで、valgrind はより正確なエラー報告を生成し、混乱も少なくなります。

一部のコンパイル最適化オプション (-O2 以上) は memcheck が誤った初期化されていないレポートを提出する原因になることがあります。valgrind のレポートをより正確にするために、コンパイル時に最適化オプションを使用しないほうがよいでしょう。

プログラムがスクリプトによって起動される場合、プログラムを起動するスクリプトのコードを修正するか、-trace-children=yesオプションを使用してスクリプトを実行することができます。

以下は、sample.cをmemcheckでチェックする例です。

ここで使用するサンプルプログラムはsample.c(下図)、使用するコンパイラはgccです。

実行プログラムの生成

gcc -g sample.c -o sample

図1

Valgrindの実行

valgrind --tool=memcheck . /sample

上記のコマンドを実行した後の出力は以下のとおりです。

図2

左の行番号のような数字(10297)がプロセスIDです。

上部の赤枠はvalgrindのバージョン情報です。

真ん中の赤枠は、テスト対象のプログラムを実行してvalgrindが発見したメモリの問題を示しています。この情報を読むことで、以下のことがわかります。

l これはメモリへの不正な書き込み操作で、不正な書き込み操作は4バイトのメモリです。

l エラーが発生したときの関数スタックと、具体的なソースコードの行番号。

l 不正な書き込み操作を行った具体的なアドレス空間。

下部の赤枠は、発見されたメモリの問題やメモリリークの概要です。メモリリークのサイズ(40バイト)も検出可能です。

Valgrindによる例

例1. 未初期化メモリの使用

コードは以下の通りです。

#include <stdio.h>

int main()

{ <未定義

int xです。

if(x == 0)

{ <未定義

printf("X is zero")。

}

は0を返します。

}

Valgrind は次のようなプロンプトを表示します。

==14222== 条件付きジャンプまたは移動は、未初期化の値に依存します。

==14222== at 0x400484: main (sample2.c:6)

Xはゼロ==14222==です。

==14222== ERROR SUMMARY: 1つのコンテキストから1つのエラー(抑制:1つのコンテキストから5つのエラー)。

==14222== malloc/free: 終了時に使用中: 0 ブロックに 0 バイトです。

==14222= malloc/free。0件の割り込み、0件の解放、0バイトの割り当て。

==14222== 検出されたエラーの数については、以下のように再実行します。-v

==すべてのヒープ・ブロックが解放されました -- リークは発生しません。

例2. 境界外のメモリの読み書き

コードは以下の通りです。

#include <stdlib.h>

#include <stdio.h>

int main(int argc,char *argv[])

{ <未定義

int len=5 です。

int i;

int *pt=(int*)malloc(len*sizeof(int))となります。

int *p=pt;

for(i=0;i<len;i++)

{p++;}

*p=5;

printf("%d",*p)。

を返します。

}

Valgrind は次のようなプロンプトを表示します。

==23045== サイズ 4 の無効な書き込み

==23045== at 0x40050A: main (sample2.c:11)

==アドレス 0x4C2E044 はサイズ 20 のブロックが割り当てられた後、0 バイトになります。

==23045== at 0x4A05809: malloc (vg_replace_malloc.c:149)

==23045== by 0x4004DF: メイン (sample2.c:7)

===23045===

==23045== サイズ4の無効な読み取り

==23045== at 0x400514: main (sample2.c:12)

==アドレス 0x4C2E044 はサイズ 20 のブロックが割り当てられた後、0 バイトになります。

==23045== at 0x4A05809: malloc (vg_replace_malloc.c:149)

==23045== by 0x4004DF: メイン (sample2.c:7)

5==23045===

==23045== ERROR SUMMARY: 2 つのコンテキストから 2 つのエラー (抑制: 1 つから 5 つ)

==23045== malloc/free: 終了時に使用中: 1 ブロックで 20 バイトです。

==23045== malloc/free: 1回の割り当て、0回の解放、20バイトが割り当てられました。

==23045== 検出されたエラーの数については、次のように再実行します。-v

==23045== 1の非フリーなブロックへのポインタを検索しています。

==23045== 66,584バイトをチェックしました。

==23045==

==23045== リークまとめ。

==23045== 確実に失われたのは、1ブロック中の20バイトです。

==23045== 失われた可能性があります: 0 ブロックに 0 バイトです。

==23045==はまだ到達可能です。0バイト/0ブロック

==23045==が抑制されました。0 bytes in 0 blocks.

==リークされたメモリの詳細を見るには、--leak-check=full を使用します。

例3.srcとdstのメモリのオーバーライド

コードは以下の通りです。

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

int main(int argc,char *argv[])

{ char x[50];

int i;

for(i=0;i<50;i++)

{x[i]=i;}とする。

strncpy(x+20,x,20); //Good

strncpy(x+20,x,21); //オーバーラップ

x[39]='\0';

strcpy(x,x+20); //Good

x[39]=40;

x[40]='\0';

strcpy(x,x+20); //オーバーラップ

は0を返します。

}

Valgrind は次のようなプロンプトを表示します。

==24139== そこで strncpy(0x7FEFFFC09, 0x7FEFFFBF5, 21)でコピー元とコピー先が重なっている。

==24139== at 0x4A0724F: strncpy (mc_replace_strmem.c:116)

==24139== by 0x400527: メイン (sample3.c:10)

==24139==

==24139== <スパン そこで strcpy(0x7FEFFFBE0, 0x7FEFFFBF4) でコピー元とコピー先が重なっている。

==24139== at 0x4A06E47: strcpy (mc_replace_strmem.c:106)

==24139== by 0x400555: メイン (sample3.c:15)

==24139==

==24139== ERROR SUMMARY: 2 つのコンテキストから 2 つのエラー (抑制: 1 つから 5 つのエラー)

==24139== malloc/free: 終了時に使用中: 0 ブロックに 0 バイトです。

==24139== malloc/free: 0件の割り込み、0件の解放、0バイトの割り当て。

==24139== 検出されたエラーの数については、以下のように再実行します。-v

==24139== 全てのヒープブロックは解放されました -- リークは発生しません。

例4. 動的メモリ管理エラー

一般的なメモリ割り当てには、静的記憶、スタック上の割り当て、ヒープ上の割り当ての3種類があります。グローバル変数は静的で、コンパイル時に割り当てられ、関数内のローカル変数はスタック上に割り当てられ、最も柔軟にメモリを使用する方法はヒープ上に割り当てることで、動的メモリ割り当てとも呼ばれます。一般的に使用される動的メモリ割り当て関数には malloc, alloc, realloc, new などがあり、動的解放関数には free, delete などがある。

動的メモリの要求が成功したら、それを自分で管理する必要がありますが、ここが最も間違えやすいところです。よくあるメモリの動的管理の間違いには、次のようなものがあります。

l 要求と解放の一貫性がない

C++はC互換であり、CとC++ではメモリの要求と解放の関数が異なるため、C++プログラムでは動的メモリ管理関数が2組存在します。Cの方法で要求されたメモリはCの方法で解放され、C++の方法で要求されたメモリはC++の方法で解放されるというのが、1つの不変のルールです。つまり、malloc/alloc/reallocで要求されたメモリはfreeで解放され、newで要求されたメモリはdeleteで解放されます。上記のプログラムでは、mallocで要求されたメモリはdeleteで解放されます。多くの場合、これは問題ではありませんが、潜在的な問題であることは間違いありません。

l リクエストとリリースのミスマッチ

どれだけのメモリが要求され、どれだけのメモリが使用終了後に解放されるか。解放されていない場合、あるいは解放が不足している場合はメモリリーク、解放が過剰な場合も問題である。上のプログラムでは、ポインタ p と pt は同じメモリブロックを指していますが、2回解放されています。

l 解放した後も読み書きができる

本来、システムはヒープ上に動的なメモリチェーンを保持しており、解放されれば、そのメモリブロックは他のセクションに割り当てられ続け、解放後にメモリにアクセスすると、他のセクションの情報を上書きしてしまい、重大なエラーとなり、上記の16行目のプログラムは解放後にもこのメモリブロックを書き込んでいるのだそうです。

次の部分には、動的メモリ管理でよくあるエラーが含まれています。

#include <stdlib.h>

#include <stdio.h>

int main(int argc,char *argv[])

{ char *p=(char*)malloc(10)。

char *pt=p;

int i;

for(i=0;i<10;i++)

{p[i]='z';}となります。

p を削除します。

p[1]='a'とする。

free(pt);

0を返します。

}

Valgrind は次のようなプロンプトを表示します。

==25811== Mismatched free() / delete / delete [].

0x4A05130 で ==25811==: operator delete(void*) (vg_replace_malloc.c:244)

==25811== by 0x400654: main (sample4.c:9)

==アドレス 0x4C2F030 はサイズ 10 のブロックに 0 バイトで割り当てられています。

0x4A05809 にある ==25811==: malloc (vg_replace_malloc.c:149)

0x400620 によって ==25811==: メイン (sample4.c:4)

==25811==

==サイズ1の無効な書き込みです。

0x40065D にある ==25811==: メイン (sample4.c:10)

==アドレス 0x4C2F031 は、サイズ 10 のブロック内で 1 バイトが解放されています。

==25811== at 0x4A05130: operator delete(void*) (vg_replace_malloc.c:244)

==25811== by 0x400654: main (sample4.c:9)

==25811==

==無効なfree()/delete/delete[]です。

==25811== at 0x4A0541E: free (vg_replace_malloc.c:233)

0x400668 による ==25811==: メイン (sample4.c:11)

==アドレス 0x4C2F030 は、サイズ 10 のブロック内で 0 バイトが解放されています。

==25811== at 0x4A05130: operator delete(void*) (vg_replace_malloc.c:244)

==25811== by 0x400654: main (sample4.c:9)

==25811==

==ERROR SUMMARY: 3 つのコンテキストから 3 つのエラー (抑制: 1 つから 5 つ)

==25811== malloc/free: 終了時に使用中: 0 ブロックに 0 バイトです。

==25811== malloc/free: 1回の割り当て、2回の解放、10バイトの割り当てがありました。

==検出されたエラーの数については、以下のように再実行します。-v

==すべてのヒープ・ブロックが解放されました -- リークは発生しません。

例5:メモリリーク

コードは以下の通りです。

#include <stdlib.h>

int main()

{ <未定義

char *x = (char*)malloc(20);

char *y = (char*)malloc(20);

x = y とする。

free(x)です。

free(y)です。

0を返します。

}

Valgrind は次のようなプロンプトを表示します。

==19013== 無効な free() / delete / delete[] です。

==19013== at 0x4A0541E: free (vg_replace_malloc.c:233)

0x4004F5 による ==19013==: メイン (sample5.c:8)

==アドレス 0x4C2E078 は、サイズ 20 のブロック内で 0 バイトが解放されています。

==19013== at 0x4A0541E: free (vg_replace_malloc.c:233)

0x4004EC による ==19013==: メイン (sample5.c:7)

==19013==

==19013== ERROR SUMMARY: 1 つのコンテキストから 1 つのエラー (抑制: 1 から 5)

==19013== malloc/free: 終了時に使用中: 1 ブロックで 20 バイトです。

==19013== malloc/free: 2回の割り当て、2回の解放、40バイトの割り当てがありました。

==19013== 検出されたエラーの数については、以下のように再実行します。-v

==19013== 1の不自由なブロックへのポインタを検索しています。

==19013== 66,584バイトをチェックしました。

==19013==

==19013== リークまとめ。

==19013== 確実に失われたのは、1ブロック中の20バイトです。

==19013== 失われた可能性があります: 0 ブロックに 0 バイトです。

==19013==はまだ到達可能です。0バイト/0ブロック

==19013==は抑制されました。0 bytes in 0 blocks.

==リークしたメモリの詳細を見るには、--leak-check=full を使用します。

例6:不正な書き込み/読み取り

コードは以下の通りです。

int main()

{ <未定義

int i, *x;

x = (int *)malloc(10*sizeof(int))。

for (i=0; i<11; i++)

x[i] = i;

free(x)です。

}

Valgrind は次のようなプロンプトを表示します。

==21483== 無効な書き込みサイズ4

==21483== at 0x4004EA: main (sample6.c:6)

==アドレス 0x4C2E058 はサイズ 40 のブロックが割り当てられた後、0 バイトになります。

==21483== at 0x4A05809: malloc (vg_replace_malloc.c:149)

==21483== by 0x4004C9: メイン (sample6.c:4)

==21483==

==21483== ERROR SUMMARY: 1 つのコンテキストから 1 つのエラー (抑制: 1 つから 5 つ)

==21483== malloc/free: 終了時に使用中: 0 ブロックに 0 バイトです。

==21483== malloc/free: 1 つの割り当て、1 つの解放、40 バイトが割り当てられました。

==21483== 検出されたエラーの数については、次のように再実行します。-v

==すべてのヒープブロックが解放されました。

例7:無効なポインタ

コードは以下の通りです。

#include <stdlib.h>

int main()

{ <未定義

char *x = malloc(10);

x[10] = 'a' とする。

free(x)です。

0を返します。

}

Valgrind は次のようなプロンプトを表示します。

==15262== サイズ1の無効な書き込みです。

==15262== at 0x4004D6: main (sample7.c:5)

==アドレス0x4C2E03Aはサイズ10のブロックがアロケートされた後、0バイトになります。

==15262== at 0x4A05809: malloc (vg_replace_malloc.c:149)

0x4004C9 による ==15262==: メイン (sample7.c:4)

==15262==

==15262== ERROR SUMMARY: 1 つのコンテキストから 1 つのエラー (抑制: 1 つから 5 つ)

==15262== malloc/free: 終了時に使用中: 0 ブロックに 0 バイトです。

==15262== malloc/free: 1回の割り当て、1回の解放、10バイトの割り当てがありました。

==15262== 検出されたエラーの数については、以下のように再実行します。-v

==すべてのヒープブロックが解放されました。

例 8: リリースの繰り返し

コードは以下の通りです。

#include <stdlib.h>

int main()

{ <未定義

char *x = malloc(10);

free(x)を使用します。

free(x)です。

0を返します。

}

Valgrind は次のようなプロンプトを表示します。

==15005== 無効なfree()/delete/delete[]です。

==15005== at 0x4A0541E: free (vg_replace_malloc.c:233)

0x4004DF による ==15005==: メイン (sample8.c:6)

==アドレス 0x4C2E030 は、サイズ 10 のブロック内で 0 バイトが解放されています。

0x4A0541E で ==15005==: フリー (vg_replace_malloc.c:233)

0x4004D6 による ==15005==: メイン (sample8.c:5)

===15005===

==15005== ERROR SUMMARY: 1 つのコンテキストから 1 つのエラー (抑制: 1 から 5)

==15005== malloc/free: 終了時に使用中: 0 ブロックに 0 バイトです。

==15005== malloc/free: 1回の割り当て、2回の解放、10バイトの割り当てがありました。

==15005== 検出されたエラーの数については、以下のように再実行します。-v

==全てのヒープブロックが解放されました。

Valgrindの制限事項

l Valgrind は静的配列(スタックに割り当てられたもの)に対して境界チェックを行いません。プログラム内で配列が宣言されている場合、その配列の境界チェックは行いません。

int main()

{ <未定義

char x[10]です。

x[11] = 'a' とする。

}

Valgrind は、ヒープ上に動的に割り当てられる配列に変更することで、境界チェックが可能になることを警告してくれません。この方法は、ちょっと損をしているような気がします。

l Valgrindはより多くのメモリを消費します - プログラムの通常の使用量の最大2倍です。多くのメモリを使うプログラムを検出するために Valgrind を使って問題に遭遇した場合、テストを実行するのに長い時間がかかることがあります。ほとんどの場合、これは問題ではありませんし、たとえ遅いとしても、テストするときだけ遅いのです。通常実行時にすでに遅いプログラムを Valgrind でテストする場合、これは大きな問題です。もしバッファオーバーフローをチェックしなければ、Valgrind はコードが書くべきでないメモリを書いていることを教えてはくれません。

付録A: パラメータ指示文

基本的なオプションです。

これらのオプションは、すべてのツールで利用可能です。

-h --help

カーネルと選択されたツールの両方を含む、すべてのオプションのヘルプを表示します。

--help-debug

help と同じで、通常は Valgrind の開発者だけが使うデバッグオプションも表示されます。

--バージョン

Valgrind カーネルのバージョン番号を表示します。ツールは独自のバージョン番号を持つことができます。これは、ツールが実行可能なカーネルのみで動作するようにするための設定です。これにより、ツールとカーネル間のバージョンの互換性に起因する奇妙な問題が発生する可能性を減らすことができます。

-q --quiet

エラーメッセージのみを表示し、静かに動作します。リグレッションテストや他の自動化されたテストメカニズムがある場合に便利です。

-v --冗長

詳細情報を表示します。ロードされた共有オブジェクト、使用されたリセット、エンジンやツールを実行しているプロセス、異常な動作に対する警告メッセージなど、プログラムに関するさまざまな側面からの追加情報を表示します。このタグを繰り返すことで、より詳細な情報を表示することができます。

-d

Valgrind 自身が送信するデバッグメッセージ。通常、Valgrind の開発者だけがこれに関心を持ちます。このフラグを繰り返すと、より詳細な出力が得られます。バグレポートを送りたい場合は、 -v -v -d -d によって生成された出力は、あなたのレポートをより効果的にします。

-tool=<toolname> [デフォルト:memcheck]。

toolname で指定した Valgrind を実行します(例:Memcheck、Addrcheck、Cachegrind など)。

-trace-children=<yes|no> [デフォルト: no].

このオプションをオンにすると、Valgrind は子プロセスまでトレースします。これはしばしば混乱を招き、通常期待するものとは異なるので、デフォルトではこのオプションはオフになっています。

-track-fds=<yes|no> [デフォルト: no].

このオプションをオンにすると、Valgrind は終了時に開いているファイルディスクリプタのリストを表示します。各ファイル記述子は、ファイルが開かれたスタック・トレースバックと、そのファイル記述子に関連する詳細(ファイル名や だから ケット情報。

-time-stamp=<yes|no> [デフォルト:no]。

このオプションをオンにすると、各メッセージの前に、番組開始からの経過時間を日、時、分、秒、ミリ秒の単位で表示するようになります。

--log-fd=<number> [デフォルト: 2, stderr].

Valgrindがすべてのメッセージを指定されたファイル記述子に出力することを指定します。デフォルトの値である 2 は、標準エラー出力 (stderr) です。これはクライアント自身の stderr の使用と干渉する可能性があり、Valgrind の出力はクライアントプログラムの stderr への出力と混在することに注意してください。

--log-file=<filename>

Valgrindが全ての情報を指定されたファイルに出力することを指定します。実際には、作成されるファイル名は filename, '.' とプロセス番号が連結され(つまり <filename>. <pid> )、プロセスごとに異なるファイルが作成されます。

--log-file-exactly=<filename>

-log-fileと似ていますが、接尾辞 ".pid"は追加されません。このオプションを設定し、Valgrind を使って複数のプロセスを追跡すると、乱雑なファイルになることがあります。

--log-file-qualifier=<VAR>

-log-fileと一緒に使用すると、ログファイル名が環境変数$VARによってフィルタリングされます。これはMPIプログラムに有効です。詳しくは、マニュアルの2.3節「注意事項」を参照してください。

-log- だから cket=<ip-address:port-number>

Valgrindが指定されたIPに、指定されたポートですべてのメッセージを出力することを指定します。1500番ポートを使用する場合、このポートは無視されることがあります。指定したポートへの接続が確立できない場合、Valgrind は標準エラー (stderr) に書き込みを出力します。このオプションは、Valgrind のリスナーと一緒に使うことが多いです。詳しくはマニュアルの2.3節 "注意事項"を参照してください。

エラーに関連するオプションです。

これらのオプションは、Memcheck などのエラーを発生させるすべてのツールに適用されますが、Cachegrind には適用されません。

--xml=<yes|no> [デフォルト:no].

このオプションをオンにすると、出力はXML形式になります。これはValgrindの出力をGUIフロントエンドのようなツールの入力として使いやすくするためのものです。現在、このオプションはMemcheckでのみ動作します。

--xml-user-comment=<string>

ユーザーコメントをXMLの先頭に追加する。--xml=yesが指定された場合のみで、それ以外は無視される。

-demangle=<yes|no> [デフォルト:yes].

C++の自動名前デコードのオン/オフを切り替えます。デフォルトではオンに設定されています。オンにすると、Valgrind はエンコードされた C++ 名を自動的に初期状態に戻すように変換しようとします。このデコーダーは g++ バージョン 2.X,3.X または 4.X で生成されたシンボルを扱えます。 名前のエンコーディングのデコードに関する重要な事実は、禁制のファイル中のデコードされた関数名は、まだデコードされていない形式を使うことです。 Valgrind は、利用できる禁制エントリを探すときに関数名をデコードしません。これは、禁制ファイルの内容が Valgrind の名前のデコード機構の状態に依存してしまい、遅く無意味なものになってしまうからです。

--num-callers=<number> [デフォルト: 12].

デフォルトでは、Valgrind はプログラムの場所を決定するのに役立つように、12レベルの関数呼び出しの関数名を表示します。この数はこのオプションで変更することができます。これは、ネストされた呼び出しのレベルが非常に深い場合に、プログラムの場所を決定するのに役立ちます。エラーメッセージは通常、上位4つの関数にしか戻りません。(現在の関数とその3つの呼び出し元の場所)。したがって、これは報告されるエラーの総数には影響しません。最大値は50です。高い設定は Valgrind の動作を遅くし、より多くのメモリを使用することになりますが、ネストされた呼び出しが多いプログラムでは有用であることに注意してください。

--error-limit=<yes|no> [デフォルト: yes].

このオプションをオンにすると、Valgrind はエラーの合計数が 10,000,000 あるいは 1,000 の異なるエラーに達すると、エラーの報告を停止します。これは、エラー追跡メカニズムが、多くのエラーを持つプログラムで大きなパフォーマンスの負担となることを避けるためです。

--error-exitcode=<number> [デフォルト: 0].

Valgrind が実行中にエラーを報告した場合の終了時の戻り値を指定します。2つのケースがあります。デフォルト値 (0) に設定すると、Valgrind が返す値は、実行をシミュレートしているプログラムの戻り値となります。ゼロ以外の値を設定すると、Valgrind が何らかのエラーを見つけた場合にこの値が返されます。これは Valgrind がテストツールスイートの一部として使われる場合に便利です。Valgrind の返り値をチェックするだけで、 Valgrind がどのテストケースでエラーを報告したかを知ることができるからです。

--show-below-main=<yes|no> [デフォルト: no] です。

デフォルトでは、エラー時のスタック・トレースバックは、main() の下の関数 (または main() がスタック・トレースバックに現れない場合は glibc の __libc_start_main() などの類似関数) を表示しません。これらのほとんどは、うんざりする C ライブラリ関数です。このオプションをオンにすると、main()配下の関数も表示されるようになります。

--suppressions=<filename> [デフォルト: $PREFIX/lib/valgrind/default.supp] です。

無視されたエラーを読み込むための追加ファイルを指定します。必要なだけ追加ファイルを使用することができます。

--gen-suppressions=<yes|no|all> [デフォルト:no].

yesに設定すると、Valgrindはエラーが表示されるたびに自動的に一時停止し、次の行を表示します: ---- Print suppression ? --- [Return/N/n/Y/C/c] ---- このプロンプトは --db-attach オプションと同じ動作をします(下記参照)。yesを選択すると、Valgrindはエラーの禁則事項をプリントアウトします。将来的にエラーメッセージを二度と見たくない場合は、カットしてファイルに貼り付けることができます。all に設定すると、Valgrind はユーザーに尋ねることなく、各エラーに対して禁止されたエントリをプリントします。このオプションは、コンパイラで調整された名前をプリントアウトする C++ プログラムに便利です。プリントアウトされる禁則事項は、できるだけ具体的であることに注意してください。関数名にワイルドカードを追加するなどして、類似のエントリーをグループ化する必要がある場合。また、2つの異なるエラーが同じ禁則事項を出力することがあるので、 Valgrind は禁則事項を複数回出力しますが、禁則事項のファイルには1つのコピーしか必要ありません(ただし、複数あっても問題は起きません)。また、禁止エントリーの名前は <Enter a ban entry name here> のようになります。名前は重要ではなく、-v オプションで使用したすべての禁止エントリーの記録を出力するために使用されるだけです。

--db-attach=<yes|no> [デフォルト:no].

このオプションをオンにすると、Valgrind はエラーが表示されるたびに一時停止して次の行を入力します: ---- Attach to debugger ? ---- [Return/N/n/Y/y/C/c] ---- Enter、またはN、Enter、n、Enterを押すと、Valgrindはこのエラーに対してデバッガを開始しません。Y, enter, または y, enterを押すと、Valgrindはデバッガを起動し、プログラムの実行中のこの時点に設定します。デバッグが終了したら、exitすると、プログラムの実行が継続されます。デバッガ内部からプログラムの実行を継続しようとしても、それは有効ではありません。C, Enter, または c, Enter, Valgrind を押しても、デバッガは起動せず、再度問い合わせることもありません。注意:-db-attach=yes は --trace-children=yes と競合します。同時に使うことはできません。この場合、valgrindは起動しません。

2002.05: これは歴史的遺物です。もしこの問題があなたに影響するならば、電子メールを送ってこの問題について訴えてください。

2002.11: ログファイルやネットワークポートに出力を送っても、何も感じないのでしょうね。気にしないでください。

--db-command=<command> [デフォルト: gdb -nw %f %p].

-db-attachでデバッガの使用方法を指定します。デフォルトのデバッガはgdbです。デフォルトのオプションは Valgrind のテンプレートをランタイムに拡張したものです。f は実行ファイルのファイル名に、%p は実行ファイルのプロセス ID に置き換わります。

Valgrind がどのようにデバッガーを起動するかを指定します。デフォルトのオプションは、構築時にGDBが検出されるかどうかによって変わることはなく、通常は/usr/bin/gdbとなります。このコマンドを使うことで、他のデバッガの呼び出しを何らかの形で指定し、置き換えることができます。

与えられたコマンド文字列は、1 つ以上の %p %f 拡張子を含むことができます。各 %p インスタンスはデバッグされるプロセスの PID として解釈され、各 %f インスタンスはデバッグされるプロセスの実行可能ファイルへのパスとして解釈されます。

--input-fd=<number> [デフォルト: 0, stdin].

db-attach=yes と --gen-suppressions=yes オプションをつけると、 Valgrind はエラーを見つけたときにキーボード入力を読むのをやめます。デフォルトでは標準入力から読み込むので、標準入力をオフにしているプログラムでは問題が発生します。このオプションを使うと、ファイルディスクリプタを指定して、代わりに標準入力から読み込むことができます。

-max-stackframe=<number> [デフォルト:2000000]。

スタックの最大値。スタックポインタがこの量より多くオフセットされている場合、Valgrind はプログラムが別のスタックに切り替わっていると見なします。プログラム中に大きなスタックアロケーションの配列がある場合、このオプションを使う必要があるかもしれません。 valgrind はプログラムのスタックポインタを記録しています。スタックポインタがこの量より多くオフセットされている場合、 Valgrind はプログラムが別のスタックに切り替わったとみなし、Memcheck はスタックポインタと同じように動作するようにします。

ポインターのオフセットがこの量を超えていない場合は、異なるものになります。通常、この仕組みはうまく機能します。しかし、プログラムがスタック上に大きな構造体を要求した場合、このメカニズムは愚かな動作をし、Memcheck は大量の不正なスタックメモリアクセスを報告します。このオプションにより、この閾値を他の値に設定することができます。このオプションは、Valgrind のデバッグ出力が必要であることを示す場合にのみ使用してください。この場合、指定すべき新しい閾値を教えてくれます。一般的に、スタックに大きなメモリチャンクを割り当てるのは悪い考えです。これは、特にメモリに制約のあるシステムや、小さなスタックで多数のスレッドをサポートするシステムで、スタック領域が不足しやすいからです。Memcheck は、スタック上のデータよりもヒープ上のデータに対してはるかに効率的なエラーチェックを実行するためです。このオプションを使用する場合、スタック上ではなくヒープ上にメモリを割り当てるようにコードを書き直すことを検討するとよいでしょう。

MALLOC()関連のオプションです。

malloc()の独自バージョン(Memcheckやmassifなど)を使用する場合、以下のオプションが利用可能です。

--alignment=<number> [デフォルト:8].

Valgrind の malloc() や realloc() などは、デフォルトでは 8 バイトにアラインされたアドレスになっています。これはほとんどのプロセッサの標準です。しかし、プログラムによっては malloc() などは常に 16 バイト以上のアライメントされたメモリを返すと思い込んでいる場合があります。この値は、8から4096の範囲内で、かつ2の累乗でなければならない。

非ジェネリックなオプション

これらのオプションはすべてのツールで利用可能で、Valgrind coreのいくつかの機能に影響を与えます。ほとんどの人はこれらのオプションを使うことはないでしょう。

--run-libc-freeres=<yes|no> [デフォルト: yes] です。

GNU C ライブラリ(libc. だから ) は、すべてのプログラムで共有され、それ自身の使用のためにいくつかのメモリを割り当てることができます。プログラムが終了するときにメモリを解放することは通常問題ではありません -- Linux カーネルはプロセスが終了するときにプロセスのすべてのリソースを再要求するので、何も問題はなく、これは単に速度低下を引き起こすだけです。 glibc の作者は、これが終了時にメモリエラーをチェックする Valgrind などのメモリチェッカに glibc のメモリリークの報告をさせてしまうと認識し、この問題を避けるために __libc_freeres() を特に提供して glibc にすべての割り当てメモリを解放できるようにしたのです。そこで、Memcheck は終了時に __libc_freeres() を実行しようとします。残念ながら、glibc のいくつかのバージョンでは、__libc_freeres はバグがあり、セグメントエラーを発生させます。これは特に Red Hat 7.1 で宣言されています。そこで、このオプションを提供して、__libc_freeresを実行するかどうかを決定します。もし、Valgrind でプログラムがうまく動いているように見えても、終了時にセグメントエラーが発生する場合は、 --run-libc-freeres=no を指定して修正する必要があるかもしれませんが、これはおそらく libc を不正に報告することになります。 だから のメモリリークを修正しました。

-sim-hints=hint1,hint2,...です。

Valgrindにプロミスキャスヒントを渡します。標準的でない、あるいは危険な方法でシミュレーションの動作を少し修正し、奇妙な機能をシミュレートするのに役立ちます。デフォルトではヒントを与えません。注意して使ってください。現在知られているヒントは以下の通りです。

lax-ioctls: ioctl の扱いが非常に緩く、サイズが正しいことだけが前提。書き込み時にバッファを完全に初期化する必要はありません。これがないと、奇妙な ioctl コマンドをたくさん持つデバイスドライバを使うときに非常に困ることになります。

l enable-inner。実行中のプログラムが Valgrind 自身である場合に、いくつかの特殊効果をオンにします。

--kernel-variant=variant1,variant2,...

システムコールと ioctl を処理すると、このプラットフォームのデフォルトカーネルで異なる variant が生成されます。これは、改良されたカーネルでの実行や、非標準の ioctl をサポートするのに役立ちます。注意深く使ってください。このオプションが何をするものなのか理解できない場合は、ほとんど必要ありません。既に知られている変数としては

l bproc: X86 プラットフォームで sys_broc システムコールをサポートします。これは BProc 上で実行することを意図しています。BProc は標準 Linux の亜種であり、クラスタを構築するために使われることもあります。

--show-emwarns=<yes|no> [デフォルト: no].

このオプションをオンにすると、Valgrindはいくつかの特定のケースでCPUエミュレーションの警告を生成します。通常、これらは控えめなものです。

--smc-check=<none|stack|all> [デフォルト:スタック]。

このオプションは Valgrind の自己修正コードの検出をコントロールします。 valgrind は検出をしない、スタック上の自己修正コードを検出する、あるいはどこでも自己修正コードを検出することができます。デフォルトのオプションは、今までに分かっている限り、ほとんどのケースをキャッチすることに注意してください。all オプションを使うと、かなり遅くなります。(しかし、ほとんどのプログラムでは、スタックに追加されるコードはほとんどないため、noneオプションで実行しても速度にはほとんど影響しない)

VALGRINDオプションのデバッグ。

また、Valgrind自体をデバッグするためのオプションもあります。一般的なものを実行する際には、それらは必要ないはずです。オプションの一覧を見たい場合は、--help-debug オプションを使ってください。

メモリチェックのオプション。

--leak-check=<no|summary|yes|full> [デフォルト:summary]。

このオプションをオンにすると、クライアントプログラムの終了時にメモリリークを検索します。メモリーリークとは、あるメモリーブロックがmallocで割り当てられたが、freeで解放されておらず、このメモリーブロックへのポインターが存在しないことを意味します。このようなメモリブロックは、それへのポインタがないため、プログラムによって解放されることはありません。summary に設定すると、Valgrind はいくつのメモリリークが発生したかを報告します。full または yes に設定すると、Valgrind は個々のリークについて詳細な情報を提供します。

--show-reachable=<yes|no> [デフォルト:no]。

このオプションがオフの場合、メモリリーク検出器は、そのブロックを指すポインタがないメモリブロックのみを表示するか、ブロックの中央へのポインタのみを検出します。このオプションがオンの場合、メモリ・リーク検出器は、ポインタが指すメモリ・ブロックも報告します。これらのブロックは、メモリ・リークが発生する可能性が最も高い場所です。あなたのプログラムは、少なくとも原則的には、これらのメモリー・ブロックを終了する前に解放する必要があるでしょう。これらのポインターを持つメモリブロックも、ポインターを持たないブロック、あるいは内部ポインターだけを持つブロックも、実際にはブロックの開始点へのポインターが存在しないので、解放したくても解放できないため、メモリリークが発生する可能性があります。

--leak-re だから lution=<low|med|high> [デフォルト:low]。

メモリリークチェックを行う際、異なるスタックをどのように同一ケースと見なすかを決定します。low に設定すると、最初の 2 つのレベルのスタックだけが一致すれば同一ケースとみなされ、med に設定すると 4 つのレベルのスタックが一致しなければならず、high に設定すると、すべてのレベルのスタックが一致しなければなりません。本格的なメモリリークチェックを行う場合は、--leak-re を使う必要があるだろう。 だから lution=high、--num-callers=40またはそれ以上の数。この場合、膨大な量の情報が生成されることに注意。そのため、 デフォルトのオプションは4つの呼び出し元とのマッチと低解像度のマッチとなっている。なお、--leak-re <スパン だから lution= の設定は、memcheck がメモリーリークを発見する能力に影響を与えません。結果の出力方法を変更するだけです。

-freelist-vol=<number> [デフォルト:5000000]。

クライアントプログラムが free (C) または delete (C++) を使用してメモリを解放した場合、そのメモリはすぐに再割り当てできるわけではありません。そのメモリはアクセス不能とマークされ、解放されたメモリのキューに入れられます。この目的は、解放されたメモリが再び利用できるようになる時点をできるだけ遅くすることです。これにより、memcheck は、メモリブロックが解放された後のこの重要な時期に、メモリブロックへの不正なアクセスをチェックすることが容易になります。このオプションは、キューが保持できるメモリの総量をバイト単位で指定します。デフォルト値は 5000000 バイトです。この数値を増やすと、memcheck が使用するメモリ量が増えますが、解放されたメモリの不正使用を検出する確率も高くなります。

--workaround-gcc296-bugs=<yes|no> [デフォルト: no].

このオプションをオンにすると、読み取り/書き込みスタックポインターの下にある小さな距離はgcc 2.96のバグであると見なされ、エラーとして報告されなくなります。この距離のデフォルトは256バイトです。gcc 2.96 は、いくつかの古い Linux ディストリビューション (RedHat 7.X) のデフォルトのコンパイラであるため、このオプションを使用する必要がある場合があることに注意してください。このオプションは必要ない場合は使わないでください。実際のエラーを許してしまう可能性があります。より良い解決策は、より新しい、バグフィックスされたバージョンのgcc/g++を使用することです。

--partial-loads-ok=<yes|no> [デフォルト: no] です。

アドレスから読み込む際に、memcheck が単語の長さをどのように扱うか、単語のアライメント、したがってどのバイトがアドレス指定可能で、どのバイトが不可能であるかを制御します。yes に設定すると、このような読み出しではアドレス指定エラーは発生しません。代わりに、不正なアドレスから読み取られたVバイトは未定義と表示され、正当なアドレスへのアクセスは通常どおりメモリにマッピングされます。noに設定すると、部分的に不正なアドレスからの読み取りは、完全に不正なアドレスからの読み取りと同じように扱われ、不正なアドレスエラーがスローされ、結果のVバイトは合法的なデータとして表示されます。このコード動作は、I <スパン SO C/C++の規格であり、問題があると考えるべきでしょう。可能であれば、このコードは修正されるべきです。このオプションは、最後の手段としての検討としてのみ行うべきです。

--undef-value-errors=<yes|no> [デフォルト: yes] です。

memcheckが未定義の値の危険な使用をチェックするかどうかを制御します。yes に設定すると、memcheck は Valgrind の一部である軽量なメモリチェックツールである Addrcheck のように振る舞い、未定義値のエラーチェックを行いません。未定義値のエラーを表示したくない場合は、このオプションを使用します。

CACHEGRINDオプションです。

I1/D1/L2キャッシュの構成を手動で指定します。サイズはバイトで表します。これら3つはスペースを入れずにカンマで区切らなければなりません。 例: valgrind --tool=cachegrind --I1=65535,2,64 I1/D1/L2 バッファは1つか2つか3つ指定することができます。手動で指定しない場合、各レベルは通常の方法(CPUIDコマンドでキャッシュの設定を取得し、失敗した場合はデフォルトを使用する)で取得した設定を使用します。

--I1=<size>,<as だから 線径(mm)

第1レベル命令バッファのサイズ、連想性、行数を指定します。

--D1=<size>,<as <スパン だから 線径(mm)

第1レベルのデータバッファリング、連想性、行のサイズを指定します。

--L2=<size>,<as <スパン だから 線径(mm)

第2レベルのバッファリングのサイズ、連想性、行数を指定する。

CALLGRINDオプション。

--heap=<yes|no> [デフォルト: yes].

このオプションをオンにすると、ヒープの使用状況が詳細に追跡されます。このオプションをオフにすると、massif.pid.txt や massif.pid.html は非常に短いものになります。

--heap-admin=<number> [デフォルト: 8].

ブロックごとに使用する管理バイト数です。glibc はアロケーターを使用しており、様々な要因によってブロックあたり 4 バイトから 15 バイトを必要とします。解放されたブロックの管理にも領域が必要ですが、massif はこれをカウントしません。

--stacks=<yes|no> [デフォルト: yes] です。

開くと、スタック情報がプロファイリング情報に含まれます。マルチスレッドプログラムでは、複数のスタックを持つことができます。

--depth=<number> [デフォルト: 3].

詳細なヒープ情報における呼び出しプロシージャの深さ。この値を大きくすると、より多くの情報が得られますが、massif はこのプログラムの実行を遅くし、より多くのメモリを使用し、大きな massif.pid.txt または massif.pid.hp ファイルを生成します。

--alloc-fn=<name>

メモリを確保するための関数を指定します。これは、malloc()を使用するラッパー関数で、無効であることが判明しているコンテキスト情報を埋めるために使用することができるので、便利です。(これらの関数は無駄な文脈情報を与え、グラフに意味のない領域を与えてしまう)。指定された関数は文脈上無視され、例えばmalloc()のように扱われる。このオプションは、コマンドライン上で複数回繰り返し、複数の関数を指定することができる。

--format=<text|html> [デフォルト:text].

ファイルの接尾辞に .txt または .html を使用して、テキストまたは HTML 形式の詳細なヒープ情報を生成します。

HELGRINDのオプションです。

--private-stacks=<yes|no> [デフォルト:no].

スレッドスタックがプライベートであると仮定します。

--show-last-access=<yes| です。 だから me|no>[デフォルト:no]。

最後のワードアクセスエラーの場所を表示します。

LACKEYオプション。

-fnname=<名前> [デフォルト: _dl_runtime_re だから lve()] を使用します。

name>関数のカウントです。

-detailed-counts=<no|yes> [デフォルト:no].

読み込み、保存、alu操作の回数。