2

SIGSEGV でクラッシュするアプリケーションがあります。

--20183-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--20183-- si_code=80;  Faulting address: 0x0;  sp: 0x409a8de60

valgrind: the 'impossible' happened:
   Killed by fatal signal
==20183==    at 0x38039981: vgPlain_arena_free (m_mallocfree.c:245)
==20183==    by 0x38001E84: die_and_free_mem (mc_malloc_wrappers.c:124)
==20183==    by 0x380688C3: vgPlain_scheduler (scheduler.c:1402)
==20183==    by 0x380913F4: run_a_thread_NORETURN (syswrap-linux.c:95)

クラッシュはランダムな場所で発生しますが、常に解放するときに発生するため、mallocチェーンを台無しにする何らかのメモリ破損が必要です。

通常、次のようなメッセージが表示されます。

Invalid write of size 8

これは、メモリが破損した場所を示しますが、メッセージはなく、ただちにクラッシュします。AFAIK valgrind はほとんどのシステムコールをカバーしているため、それらの呼び出しに関連する問題も報告されるので...

私の理論上の (*) 質問は、どのようなバグを探すべきかということです。valgrind が検出できない無効な書き込みにはどのようなものがありますか?

(*): 私が言ったように、実際のコードを求めないでください。これは理論的な質問です。

副次的な質問: 問題をキャッチする他のツールはありますか?

4

2 に答える 2

3

ヒープ上の割り当てのみがチェックされ、グローバル/スタック変数はチェックされません。

バッファ オーバーランが有効なメモリ (別の割り当てられたチャンク) にアクセスした場合、バッファ オーバーランは捕捉されません。次の例では、valgrind はオーバーランを報告しません (もちろん、これはすべて、使用するメモリ アロケータに依存します...)。

int main() {
    char* a = malloc(1024);
    char* b = malloc(1024);
    *(a+1600) = '!';
}

私の場合、valgrind の ptrcheck ツール ( --tool=exp-ptrcheck) が問題を発見しました。

于 2012-11-23T16:34:23.897 に答える
2

これが最近変更されていない限り、Valgrind の Memcheck ツールは、スタック配列境界の上書きを検出できません。これにより、Valgrind が認識できないあらゆる種類の楽しい問題が発生する可能性があります。

私は掘り下げて、スタック変数の破損を検出できると主張するAnnelidと呼ばれるユーザー作成ツールを見つけました。そのような問題を見つけるのに役立つかもしれません。

Valgrind の内部に関する私の経験のほとんどは、そのメモリ チェック システムを中心に展開しているため、他の誰かがその他の側面と、検出できるものと検出できないものについて詳しく説明できるかもしれません。

于 2012-11-14T14:15:12.433 に答える