C(++)言語: valgrindの使い方 (memcheck)
Kazuki Ohta, 2006/05/20

「Binary Hacks」
(2-1) Memcheck: メモリエラーを検出する
Memcheckが検出出来るエラーには以下のようなモノが有る。- メモリリーク
- 初期化されていない値の使用
- freeされた領域へのアクセス
- mallocされた領域より後の領域へのアクセス
- 不正なスタック領域へのアクセス
- malloc/new/new []とfree/delete/delete []の対応の不一致
- memcpyでsrcとdestの領域が被っている
(2-1-1) Memcheck: メモリリーク
static char *s;
void leaking(void)
{
s = (char*)malloc(100);
s[0] = 'a';
}
int main(void)
{
leaking();
leaking();
leaking();
}
==29024== LEAK SUMMARY: ==29024== definitely lost: 200 bytes in 2 blocks. ==29024== possibly lost: 0 bytes in 0 blocks. ==29024== still reachable: 100 bytes in 1 blocks. ==29024== suppressed: 0 bytes in 0 blocks. ==29024== Use --leak-check=full to see details of leaked memory.
==29034== 200 bytes in 2 blocks are definitely lost in loss record 2 of 2 ==29034== at 0x1B8FF8A2: malloc (vg_replace_malloc.c:149) ==29034== by 0x8048387: leaking (in /home/kzk/testprogram/c/valgrind/a.out) ==29034== by 0x80483BA: main (in /home/kzk/testprogram/c/valgrind/a.out) ==29034== ==29034== LEAK SUMMARY: ==29034== definitely lost: 200 bytes in 2 blocks. ==29034== possibly lost: 0 bytes in 0 blocks. ==29034== still reachable: 100 bytes in 1 blocks. ==29034== suppressed: 0 bytes in 0 blocks.
(2-1-2) Memcheck: 初期化されていない値の使用
以下の様なソースコードに対してvalgrindを実行する。
int main(void)
{
int x;
printf("%d\n", x);
}
==28871== Conditional jump or move depends on uninitialised value(s) ==28871== at 0x1B9515B9: vfprintf (in /lib/tls/i686/cmov/libc-2.3.5.so) ==28871== by 0x1B95871F: printf (in /lib/tls/i686/cmov/libc-2.3.5.so) ==28871== by 0x80483A3: main (in /home/kzk/testprogram/c/valgrind/a.out)
(2-1-3) Memcheck: freeされた領域へのアクセス
int main(void)
{
char *s = (char*)malloc(10);
free(s);
s[0] = 'a';
}
==28890== Invalid write of size 1 ==28890== at 0x80483F5: main (in /home/kzk/testprogram/c/valgrind/a.out) ==28890== Address 0x1BA49028 is 0 bytes inside a block of size 10 free'd ==28890== at 0x1B90044F: free (vg_replace_malloc.c:235) ==28890== by 0x80483EE: main (in /home/kzk/testprogram/c/valgrind/a.out)
int main(void)
{
char *s = (char*)malloc(10);
free(s);
free(s);
}
==28933== Invalid free() / delete / delete[] ==28933== at 0x1B90044F: free (vg_replace_malloc.c:235) ==28933== by 0x80483FC: main (in /home/kzk/testprogram/c/valgrind/a.out) ==28933== Address 0x1BA49028 is 0 bytes inside a block of size 10 free'd ==28933== at 0x1B90044F: free (vg_replace_malloc.c:235) ==28933== by 0x80483EE: main (in /home/kzk/testprogram/c/valgrind/a.out)
(2-1-4) Memcheck: mallocされた領域より後の領域へのアクセス
int main(void)
{
char *s = (char*)malloc(10);
s[10] = 'a';
}
==28909== Invalid write of size 1 ==28909== at 0x80483AA: main (in /home/kzk/testprogram/c/valgrind/a.out) ==28909== Address 0x1BA49032 is 0 bytes after a block of size 10 alloc'd ==28909== at 0x1B8FF8A2: malloc (vg_replace_malloc.c:149) ==28909== by 0x804839D: main (in /home/kzk/testprogram/c/valgrind/a.out)
(2-1-5) Memcheck: malloc/new/new []とfree/delete/delete []の対応の不一致
C++を用いる。
int main(void)
{
char *s = new char[10];
delete s;
}
==29065== Mismatched free() / delete / delete [] ==29065== at 0x1B9006E8: operator delete(void*) (vg_replace_malloc.c:246) ==29065== by 0x80484BE: main (in /home/kzk/testprogram/c/valgrind/a.out) ==29065== Address 0x1BB5D028 is 0 bytes inside a block of size 10 alloc'd ==29065== at 0x1B9000EB: operator new[](unsigned) (vg_replace_malloc.c:197) ==29065== by 0x80484AD: main (in /home/kzk/testprogram/c/valgrind/a.out)
[ return ]