Valgrind簡単な使い方

6367 ワード


Valgrind簡単な使い方
Valgrindの主な著者Julian Sewardは今年のGoogle-O'Reillyオープンソース大賞の一つであるBest Tool Makerを受賞したばかりだ.彼の作品を見てみましょう.ValgrindはLinux上で実行されるシミュレーション技術に基づくプログラムデバッグと分析ツールで、カーネル--ソフトウェア合成のCPU、一連の小さなツールを含み、各ツールはタスク--デバッグ、分析、テストなどを完成することができます.Valgrindはメモリの漏れやメモリの違反を検出したり、cacheの使用などを分析したりすることができ、柔軟で軽くて強く、プログラムの間違いの心臓をまっすぐに通すことができ、プログラマーのスイスの軍刀と言える.一.Valgrind概観Valgrindの最新版は3.2.0で、一般的に以下のツールが含まれています:1.Memcheckで最も一般的なツールは、プログラムに発生するメモリの問題を検出するために使用され、すべてのメモリの読み書きが検出され、malloc()/free()/new/deleteの呼び出しがキャプチャされます.したがって、以下の問題を検出することができる:1.初期化されていないメモリの使用;2.リード/ライト解放後のメモリブロック;3.リード/ライトがmallocに割り当てられたメモリブロックを超えている.4.読み取り/書き込みが不適切なスタック内のメモリブロック;5.メモリが漏れ、1つのメモリへのポインタが永遠に失われる.6.不正なmalloc/freeまたはnew/deleteマッチング;7,memcpy()相関関数のdstとsrcポインタが重なる.これらの問題はC/C++プログラマーが最も頭を悩ませる問題であり、Memcheckはここで助かりました.2.Callgrindとgprofのような分析ツールですが、プログラムの実行観察はさらに細かく、より多くの情報を提供することができます.gprofとは異なり、ソースコードのコンパイル時に特別なオプションを追加する必要はありませんが、デバッグオプションを追加することは推奨されます.Callgrindはプログラムの実行時のいくつかのデータを収集し、関数呼び出し関係図を確立し、cacheシミュレーションを選択的に行うこともできる.実行が終了すると、分析データがファイルに書き込まれます.callgrind_annotateはこのファイルの内容を読み取り可能な形式に変換することができます.3.CAchegrind Cacheアナライザ、それはCPUの中の1級のキャッシュI 1、Dlと2級のキャッシュを模擬して、正確にプログラムの中のcacheの紛失と命中を指摘することができます.必要に応じて、cacheの損失回数、メモリ参照回数、および各行コード、各関数、各モジュール、プログラム全体で生成される命令数も提供できます.これはオプティマイザにとって非常に役立ちます.4.Helgrind主にマルチスレッドプログラムで発生する競合問題をチェックするために使用されます.Helgrindは、メモリに複数のスレッドがアクセスし、一貫してロックされていない領域を探します.これらの領域は、スレッド間の同期が失われ、発掘しにくいエラーを引き起こすことが多いです.Helgrindは「Eraser」という競合検出アルゴリズムを実現し,報告エラーの回数を減らすためにさらに改良した.しかし、Helgrindはまだ実験段階にある.5.プログラムがスタックでどれだけのメモリを使用しているかを測定し、スタック、スタック管理ブロック、スタックのサイズを教えてくれるMassifスタックアナライザ.Massifはメモリの使用を減らすのに役立ち、仮想メモリを備えた現代システムでは、プログラムの実行を加速させ、プログラムが交換領域にとどまる確率を減らすことができます.また、lackeyとnulgrindも提供されます.Lackeyは小型のツールで、めったに使いません.Nulgrindは開発者にツールの作成方法を示すだけです.私たちは紹介しません.二.Valgrind Valgrindの使用は非常に簡単です.valgrindコマンドのフォーマットは、valgrind[valgrind-options]your-prog[your-prog options]の一般的なオプションです.オプションの役割-h--helpはヘルプ情報を表示します.--versionにはvalgrindカーネルのバージョンが表示され、各ツールにはそれぞれのバージョンがあります.-q--quietは静かに動作し、エラー情報のみを印刷します.-v--verboseより詳細な情報を印刷します.--tool=[default:memcheck]で最も一般的なオプションです.valgrindのtoolnameというツールを実行します.ツール名を省略すると、デフォルトでmemcheckが実行されます.--db-attach=[default:no]はデバッガにバインドされ、デバッグエラーが容易です.その具体的な使用例を見てみましょう.メモリの漏洩があるCプログラムを構築します.以下のようにします.
#include <stdio.h>
#include <string.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) 
{ 
int i; 
f(); 
printf("i=%d/n",i); //problem 3: use uninitialised value. 
return 0; 
} 
はmemleakとして保存する.cをコンパイルし、valgrindで検出します.
$ gcc -Wall -o memleak memleak.c
$ valgrind --tool=memcheck ./memleak
次のエラーメッセージが表示されます.
==3649== Invalid write of size 4
==3649== at 0x80483CF: f (in/home/wangcong/memleak)
==3649== by 0x80483EC: main (in/home/wangcong/memleak)
==3649== Address 0x4024050 is 0 bytes after a block of size 40 alloc'd
==3649== at 0x40051F9: malloc (vg_replace_malloc.c:149)
==3649== by 0x80483C5: f (in/home/wangcong/memleak)
==3649== by 0x80483EC: main (in/home/wangcong/memleak)
前の3649はプログラム実行時のプロセス番号です.最初の行は、不正な書き込みであるエラータイプを示します.次は、main()呼び出しのf()関数でエラーが発生した場所を示します.
==3649== Use of uninitialised value of size 4
==3649== at 0xC3A264: _itoa_word (in/lib/libc-2.4.so)
==3649== by 0xC3E25C: vfprintf (in/lib/libc-2.4.so)
==3649== by 0xC442B6: printf (in/lib/libc-2.4.so)
==3649== by 0x80483FF: main (in/home/wangcong/memleak)
このエラーは、main()呼び出しのprintf()関数で初期化されていない値を使用します.ここでの関数呼び出し関係はスタックによって追跡されるため、特にC++のSTLを使用する場合、非常に多い場合があります.他のエラーは、libc関数に初期化されていない値を渡すことによって検出されます.プログラムの実行が完了すると、valgrindは小さなまとめを示します.
==3649== ERROR SUMMARY: 20 errors from 6 contexts (suppressed: 12 from 1)
==3649== malloc/free: in use at exit: 40 bytes in 1 blocks.
==3649== malloc/free: 1 allocs, 0 frees, 40 bytes allocated.
==3649== For counts of detected errors, rerun with: -v
==3649== searching for pointers to 1 not-freed blocks.
==3649== checked 47,256 bytes.
==3649==
==3649== LEAK SUMMARY:
==3649== definitely lost: 40 bytes in 1 blocks.
==3649== possibly lost: 0 bytes in 0 blocks.
==3649== still reachable: 0 bytes in 0 blocks.
==3649== suppressed: 0 bytes in 0 blocks.
==3649== Use --leak-check=full to see details of leaked memory.
どのくらいのメモリが割り当てられ、解放され、どのくらいのメモリが漏洩しているかがよくわかります.これは、メモリの漏洩を検索するのに便利です.次に、プログラムを再コンパイルし、デバッガをバインドします.
$ gcc -Wall -ggdb -o memleak memleak.c
$ valgrind --db-attach=yes --tool=memcheck ./memleak
エラーが発生すると、valgrindはデバッガを自動的に起動します(一般的にgdb):
==3893== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ---- y
starting debugger
==3893== starting debugger with cmd:/usr/bin/gdb -nw/proc/3895/fd/1014 3895
gdbを終了した後、valgrindに戻ってプログラムを実行することができます.
上記のプログラムを使用してcallgrindを使用して効率を分析します.
$ valgrind --tool=callgrind ./memleak
Callgrindは多くの出力を行い、最後に現在のディレクトリの下にファイルを生成します:callgrind.out.pid.callgrind_でannotateで確認するには、次の手順に従います.
$ callgrind_annotate callgrind.out.3949
詳細は列挙されています.また、callgrindがプログラムを実行するときにcallgrind_を使用することもできます.コントロールは、プログラムの実行を観察し、その実行を妨害しません.
cachegrindの表現を見てみましょう.
$ valgrind --tool=cachegrind ./memleak
次の情報が得られます.
==4073== I refs: 147,500
==4073== I1 misses: 1,189
==4073== L2i misses: 679
==4073== I1 miss rate: 0.80%
==4073== L2i miss rate: 0.46%
==4073==
==4073== D refs: 61,920 (46,126 rd + 15,794 wr)
==4073== D1 misses: 1,759 ( 1,545 rd + 214 wr)
==4073== L2d misses: 1,241 ( 1,062 rd + 179 wr)
==4073== D1 miss rate: 2.8% ( 3.3% + 1.3% )
==4073== L2d miss rate: 2.0% ( 2.3% + 1.1% )
==4073==
==4073== L2 refs: 2,948 ( 2,734 rd + 214 wr)
==4073== L2 misses: 1,920 ( 1,741 rd + 179 wr)
==4073== L2 miss rate: 0.9% ( 0.8% + 1.1% )
上は命令キャッシュ,I 1,L 2 iキャッシュ,のアクセス情報であり,総アクセス数,ロス数,ロス率を含む.
真ん中にはデータキャッシュ,D 1とL 2 dキャッシュ,のアクセスに関する情報,以下のL 2は個別の情報をキャッシュする.Cachegrindもcachegrindというファイルを生成します.out.pid、cg_annotateで読み取ります.出力はより詳細なリストです.Massifの使用はcachegrindと似ていますが、massifという名前も生成されます.pid.psのPostScriptファイルには、スタックの使用状況を説明するカラーマップが1枚しかありません.
以上はvalgrindの使用を簡単に説明しただけで、より多くの情報は添付のドキュメントで入手できます.valgrindのホームページにアクセスできます.http://www.valgrind.org.valgrindを正しく合理的に使用することを学ぶことはデバッグに役立ちます
http://www.cnblogs.com/sunyubo/archive/2010/05/05/2282170.html