4

Valgrind がセグメンテーション違反をキャッチできるようにメモリを追跡していることは承知しています。しかし、次のセグメンテーション違反をキャッチしないのはなぜですか?

int main() {
    char *x = calloc(16, 1);
    char *y = calloc(16, 1);

    x[80] = 'c';
    y[-80] = 'c';

    printf("%c %c\n", *x, *y);
    return 0;
}

ヒープ内の境界外アクセスをキャッチすることになっていませんか? Valgrindのドキュメントによると:

But it should detect many errors that could crash your program (eg. cause a segmentation fault).
4

2 に答える 2

6

あなたはヴァルグリンドに、それが可能である以上の力を与えていると思います。

さまざまなクラスのエラーを検出してユーザーに報告しようとしますが、検出しようとするエラーのクラスの一部であっても、すべてのエラーを検出することはできません。

この場合、扱っているのは配列への範囲外の書き込みであり、valgrind がそれをキャッチできた場合、「無効な書き込み」エラーとして報告されます。それらは、既知のヒープ ブロックの一部であるという点でどのアドレスが「有効」であるかを追跡することによって検出されます。

問題は、配列の先頭または末尾をはるかに超えてインデックスを作成すると、実際には隣接するブロックの有効なアドレスであるアドレスになってしまう可能性があるため、valgrind にはまったく問題ないように見えることです。これが発生する可能性を減らすために、valgrind はブロックの両側にパディングの領域 (「レッド ゾーン」と呼ばれる) を追加しますが、これはデフォルトで 16 バイトのみです。

オプションを使用してレッド ゾーンのサイズを大きくすると--redzone-size=128、valgrind がこのプログラムのエラーを検出することがわかります。

于 2012-10-31T21:23:37.243 に答える
1

私のために働く:

==24344== Memcheck, a memory error detector.
==24344== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==24344== Using LibVEX rev 1854, a library for dynamic binary translation.
==24344== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==24344== Using valgrind-3.3.1-Debian, a dynamic binary instrumentation framework.
==24344== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==24344== For more details, rerun with: -v
==24344== 
==24344== Invalid write of size 1
==24344==    at 0x8048419: main (testValgrind.c:5)
==24344==  Address 0x418f078 is 0 bytes after a block of size 16 alloc'd
==24344==    at 0x4021E22: calloc (vg_replace_malloc.c:397)
==24344==    by 0x804840F: main (testValgrind.c:3)
==24344== 
==24344== Invalid write of size 1
==24344==    at 0x8048422: main (testValgrind.c:6)
==24344==  Address 0x418f018 is 16 bytes before a block of size 16 alloc'd
==24344==    at 0x4021E22: calloc (vg_replace_malloc.c:397)
==24344==    by 0x80483F8: main (testValgrind.c:2)

==24344== 
==24344== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 12 from 1)
==24344== malloc/free: in use at exit: 32 bytes in 2 blocks.
==24344== malloc/free: 2 allocs, 0 frees, 32 bytes allocated.
==24344== For counts of detected errors, rerun with: -v
==24344== searching for pointers to 2 not-freed blocks.
==24344== checked 58,940 bytes.
==24344== 
==24344== LEAK SUMMARY:
==24344==    definitely lost: 32 bytes in 2 blocks.
==24344==      possibly lost: 0 bytes in 0 blocks.
==24344==    still reachable: 0 bytes in 0 blocks.
==24344==         suppressed: 0 bytes in 0 blocks.
==24344== Rerun with --leak-check=full to see details of leaked memory.
于 2012-10-31T21:20:50.153 に答える