Valgrind

Valgrindは、メモリデバッグや、メモリリークの検出、スレッドエラーの検出、プロファイリングなどを行うための仮想機械を利用したソフトウェア開発ツールである。Valgrindという名前は、北欧神話におけるヴァルハラへの入り口の名に由来している。

Valgrindは元々x86上のLinux用のメモリデバッグツールとして設計されたが、開発が進んだ結果、バグ検出やプロファイラといった動的解析ツールのための汎用のフレームワークとなっている。Valgrindは多数のLinux関連のプロジェクトで使用されている。ValgrindはGNU General Public Licenseの元でリリースされているフリーソフトウェアである。

1. 概要
-----

Valgrindは、本質的にはJITコンパイラの技術を用いた仮想機械である。元々のプログラムそのものがホストのプロセッサで直接実行されるわけではない。代わりにVEXと呼ぶライブラリを使い、Valgrindはまずプログラムを中間表現に変換する。中間表現自体はプロセッサ非依存であり、SSAベースである。変換の後、Valgrindが中間表現をマシンコードに再度変換してホストプロセッサで実行させるが、その前後で「ツール」はIRに対して自由に操作を行うことができる。かなりのパフォーマンスがこれらの変換の過程で損なわれ、プログラムはValgrind上では通常より4〜5倍低速に動作する。しかし、仮想機械によるIRの形態は計測・解析・デバッグには適している。これによりツールの開発が簡単になり、大半のプロジェクトでは、デバッグ中のこの程度の性能の低下は大きな問題とはならない。

システムコールも、ホストOSのシステムコールを呼び出す前にValgrindで一度ハンドリングされる。仮想機械として仮想化するのはCPUとメモリのみであり、それ以外のハードウェアはホストOSのものをそのまま使う。

2. ツール
------

Valgrindには、多数のツールが含まれている。また、外部から提供されているものもある。

2.1. Memcheck
-------------

最もよく利用されている標準のツールはMemcheckである。Memcheckはほぼすべての命令に特別な計測用のコードを挿入し、「正当性」があり、「アドレス可能」であるかという情報が、それぞれ//Vビット//および//Aビット//に格納されているかを追跡する。データは移動したり加工されたりするが、計測用のコードは1ビットレベルで正確であるようにA、Vビットを追跡する。他のメモリチェックツールなどは、対照的に未初期化メモリのコピーの検出のみ行う。

さらに、Memcheckは標準のCメモリアロケータを独自の実装に置き換え、割り当て済みブロックの前後にメモリガードを挿入する。この機能により、Memcheckはプログラムが割り当てられたブロックよりわずかに外側の領域を読み書きするoff-by-oneエラーを検出できる。

Memcheckが検出や警告可能な問題には、下記のものがある。

初期化されていないメモリの使用
freeされたメモリの読み書き
mallocされたブロックの終端以降への読み書き
メモリリークこうした機能への代償として性能が低下する。Memcheckの元で動作するプログラムはValgrindなしで動作する場合と比べて5倍から20倍遅く、より多くのメモリを使用する。したがって、ほとんどの開発者は常にMemcheckの元でコードを走らせることはしない。特定のバグを解析したり、潜在的なバグがないことを検証するために使用するのが最も典型的な方法である。

パフォーマンスのペナルティに加えて、Memcheckの重大な制約事項は、ヒープメモリに対するチェックツールであり、スタック変数・静的変数に対する境界違反を検出することができない点である。下記のコードは、コメントに示すようなエラーが存在するにもかかわらずMemcheckでは合格となる。これらの問題を検出するためにSGCheckが開発中である。

int Static[5];

int main { int Stack[5]; Static[5] = 0; /* Static[0] から Static[4] が存在し、Static[5] は境界外 */ Stack [5] = 0; /* Stack[0] から Stack[4] が存在し、Stack[5] は境界外 */ return 0; }<WtXmlEndTag />

この種類のエラーが検出できないと、ソフトウェアがバッファオーバーランを生じた場合、古典的なスタック破壊の脆弱性攻撃に対してセキュリティホールになりうるため、注意が必要である。

2.2. その他
--------

Memcheck以外に、Valgrindには下記のツールが標準で同梱されている。

Cachegrind：キャッシュプロファイラ。グラフィカルユーザインタフェースのKCacheGrindを含む。
Callgrind：コールグラフ生成。キャッシュとブランチ予測用のプロファイラ。
Helgrind：スレッドエラーの検出。マルチスレッドのコードにおける競合状態を検出可能なツール
DRD：スレッドエラーの検出
Massif：ヒーププロファイラ
DHAT：動的ヒープ解析
SGCheck：スタック配列とグローバル配列のオーバーラン検出
BBV：基本ブロックベクター生成ツール
Lackey：ツールのサンプルコード
Nulgrind：何もしないツールこのツールはバージョン3.2.0の時点で削除された。

Addrcheck：Memcheckの軽量版であり、少ないメモリ消費で高速に動作するが、少ないメモリの問題しか検出できない。

3. サポートされているプラットフォーム
--------------------

バージョン3.10.0現在、Valgrindは以下のプラットフォームをサポートしている。

Linux - x86、x86-64、ARM、PPC32、PPC64、s390x、MIPS32、MIPS64
Android - ARM、x86、MIPS32
macOS - x86、x86-64、そのほか、Unix系プラットフォームへの非公式な移植版が存在する。

Microsoft Windows向けの移植版は現時点では存在しないが、Linux上で動作するWindowsソフトウェアをデバッグするためWineと接続することができる実験的なバージョンが存在する。プラットフォームのサポートを増やすことは長期的な目標であるが、プロジェクトの性質から非常に多くの作業を必要とする。

4. 開発者
------

Valgrindの元々の開発者は、Julian Sewardであり、彼は2006年にValgrindに関する功績でGoogle-O'Reilly Open Source Awardを受賞した。他にも多数の開発者も重要な貢献を行っており、Cerion Armour-Brown、Jeremy Fitzhardinge、Tom Hughes、Nicholas Nethercote、Paul Mackerras、Dirk Mueller、Josef Weidendorfer、Robert Walshなどが挙げられる。

5. 脚注
-----

6. 参考文献
-------

title = Using Valgrind to detect undefined value errors with bit-precision

7. 外部リンク
--------

[1]
[2]
[3]