C Language
Valgrind
サーチ…
構文
- valgrind プログラム名 オプション引数 < テスト入力
備考
Valgrindは、Cプログラムのメモリ管理に関するエラーを診断するために使用できるデバッグツールです。 Valgrindは、割り当てられた領域を越えた書き込みや読み込み、 free()
への無効な呼び出しを含む、無効なポインタ使用法などのエラーを検出するために使用できます。また、メモリプロファイリングを行う関数を使用してアプリケーションを改善するためにも使用できます。
詳細はhttp://valgrind.orgを参照してください。
ランニングヴァルグリンド
valgrind ./my-program arg1 arg2 < test-input
これにより、プログラムが実行され、割り振られた割り当ておよび割り当て解除のレポートが生成されます。また、初期化されていないメモリの使用、奇妙な場所への参照の逆参照、mallocを使って割り当てられたブロックの終了を書き留めたり、ブロックを解放したりするといった一般的なエラーについて警告します。
フラグの追加
次のようなテストをさらにオンにすることもできます。
valgrind -q --tool=memcheck --leak-check=yes ./my-program arg1 arg2 < test-input
(多くの)オプションの詳細については、valgrind --helpを参照するか、出力の意味についてはhttp://valgrind.org/のドキュメントを参照してください。
失われたバイト数 - 無料で忘れる
mallocを呼び出すがフリーではないプログラムは次のとおりです。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char *s;
s = malloc(26); // the culprint
return 0;
}
余分な引数がなければ、valgrindはこのエラーを探しません。
しかし、 --leak-check=yes
または--tool=memcheck
にすると、プログラムがデバッグモードでコンパイルされた場合、メモリリークの原因となった行が表示され、表示されます。
$ valgrind -q --leak-check=yes ./missing_free
==4776== 26 bytes in 1 blocks are definitely lost in loss record 1 of 1
==4776== at 0x4024F20: malloc (vg_replace_malloc.c:236)
==4776== by 0x80483F8: main (missing_free.c:9)
==4776==
プログラムがデバッグモードでコンパイルされていない場合(GCCの-g
フラグなど)、関連する関数のどこでリークが発生したのか、行は表示されません。
これは、私たちに戻って、その行に割り当てられたブロックを見て、それがなぜ解放されなかったのかを見るために追跡しようとします。
Valgrindの使用中に発生する最も一般的なエラー
Valgrindは、書式(file.c:line_no)
で各行の最後にエラーが発生した行を提供します。 valgrindのエラーは次のようにまとめられています。
ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
最も一般的なエラーは次のとおりです。
- 不正な読み取り/書き込みエラー
==8451== Invalid read of size 2
==8451== at 0x4E7381D: getenv (getenv.c:84)
==8451== by 0x4EB1559: __libc_message (libc_fatal.c:80)
==8451== by 0x4F5256B: __fortify_fail (fortify_fail.c:37)
==8451== by 0x4F5250F: __stack_chk_fail (stack_chk_fail.c:28)
==8451== by 0x40059C: main (valg.c:10)
==8451== Address 0x700000007 is not stack'd, malloc'd or (recently) free'd
これは、コードがプログラムに属していないメモリにアクセスし始めるときに発生します。アクセスされるメモリのサイズも、どの変数が使用されたかを示します。
- 初期化されていない変数の使用
==8795== 1 errors in context 5 of 8:
==8795== Conditional jump or move depends on uninitialised value(s)
==8795== at 0x4E881AF: vfprintf (vfprintf.c:1631)
==8795== by 0x4E8F898: printf (printf.c:33)
==8795== by 0x400548: main (valg.c:7)
エラーによると、線7におけるmain
のvalg.c
、呼び出しがするprintf()
ために初期化されていない変数渡さprintf
。
- メモリの不正な解放
==8954== Invalid free() / delete / delete[] / realloc()
==8954== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8954== by 0x4005A8: main (valg.c:10)
==8954== Address 0x5203040 is 0 bytes inside a block of size 240 free'd
==8954== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8954== by 0x40059C: main (valg.c:9)
==8954== Block was alloc'd at
==8954== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8954== by 0x40058C: main (valg.c:7)
valgrindによると、コードはvalg.c
10行目で違法にメモリを解放し(2回目)、 9行目ですでに解放されていたのに対し、 7行目ではブロック自体にメモリが割り当てられました。