Memcheck
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/12/04 02:14 UTC 版)
「Valgrind」の記事における「Memcheck」の解説
最もよく利用されている標準のツールはMemcheckである。Memcheckはほぼすべての命令に特別な計測用のコードを挿入し、「正当性」(初期化が行われるまでは、割り当て済みでないメモリはすべて無効であるか、未定義である)があり、「アドレス可能」(メモリアドレスが割り当て済みで、解放されていないメモリブロックを指している)であるかという情報が、それぞれVビットおよびAビットに格納されているかを追跡する。データは移動したり加工されたりするが、計測用のコードは1ビットレベルで正確であるようにA、Vビットを追跡する。他のメモリチェックツール(IBM Rational Purify)などは、対象的に未初期化メモリのコピーの検出のみ行う(ただし、必ずしも問題があるわけではない)。 さらに、Memcheckは標準のCメモリアロケータを独自の実装に置き換え、割り当て済みブロックの前後にメモリガード(無効に設定されたAビットを持っている)を挿入する。この機能により、Memcheckはプログラムが割り当てられたブロックよりわずかに外側の領域を読み書きするoff-by-oneエラーを検出できる(この問題に対する別の対応策として、コンパイラに境界を持ったポインタを実装し、特にヒープではなくスタックに確保されたメモリのメモリエラーの検出漏れを低減させる方法があるが、計測するバイナリコードをすべてリコンパイルする必要がある)。 Memcheckが検出や警告可能な問題には、下記のものがある。 初期化されていないメモリの使用 freeされたメモリの読み書き mallocされたブロックの終端以降への読み書き メモリリーク こうした機能への代償として性能が低下する。Memcheckの元で動作するプログラムはValgrindなしで動作する場合と比べて5倍から20倍遅く、より多くのメモリを使用する(メモリ確保ごとにかなりのメモリを追加で消費する)。したがって、ほとんどの開発者は常にMemcheck(あるいは他のValgrindツール)の元でコードを走らせることはしない。特定のバグを解析したり、(Memcheckが検出可能な種類の)潜在的なバグがないことを検証するために使用するのが最も典型的な方法である。 パフォーマンスのペナルティに加えて、Memcheckの重大な制約事項は、ヒープメモリに対するチェックツールであり、スタック変数・静的変数に対する境界違反を検出することができない点である。下記のコードは、コメントに示すようなエラーが存在するにもかかわらずMemcheckでは合格となる。これらの問題を検出するためにSGCheckが開発中である。 int Static[5];int main(void) { int Stack[5]; Static[5] = 0; /* Static[0] から Static[4] が存在し、Static[5] は境界外 */ Stack [5] = 0; /* Stack[0] から Stack[4] が存在し、Stack[5] は境界外 */ return 0;} この種類のエラーが検出できないと、ソフトウェアがバッファオーバーランを生じた場合、古典的なスタック破壊の脆弱性攻撃に対してセキュリティホールになりうるため、注意が必要である。
※この「Memcheck」の解説は、「Valgrind」の解説の一部です。
「Memcheck」を含む「Valgrind」の記事については、「Valgrind」の概要を参照ください。
- Memcheckのページへのリンク