Valgrind

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動: 案内検索
Valgrind
作者 The Valgrind Developers
最新版 3.9.0 / 2013年10月31日(11か月前) (2013-10-31
プログラミング言語 C言語, アセンブリ言語
対応OS Linux, Android, OS X
サポート状況 開発中
種別 メモリデバッガ, プロファイラ
ライセンス GNU General Public License
公式サイト valgrind.org
テンプレートを表示

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

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

概要[編集]

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

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

ツール[編集]

多数のツールが 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 の重大な制約事項は、ヒープメモリに対するチェックツールであり、スタック変数・静的変数に対する境界違反を検出することができない点である[3]。下記のコードは コメントに示すようなエラーが存在するにもかかわらず 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 には下記のツールが標準で同梱されている。

  • Cachegrind:キャッシュプロファイラ。グラフィカルユーザインタフェースの KCacheGrind を含む。
  • Callgrind:コールグラフ生成。キャッシュとブランチ予測用のプロファイラ。
  • Helgrind:スレッドエラーの検出。マルチスレッドのコードにおける競合状態を検出可能なツール
  • DRD:スレッドエラーの検出
  • Massif:ヒーププロファイラ
  • DHAT:動的ヒープ解析
  • SGCheck:(実験的な)スタック配列とグローバル配列のオーバーラン検出
  • BBV:(実験的な)基本ブロックベクター生成ツール
  • Lackey:ツールのサンプルコード
  • Nulgrind:何もしないツール(ベンチマーク用およびサンプル用)

このツールはバージョン 3.2.0の時点で削除された。

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

サポートされているプラットフォーム[編集]

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

その他、Unix系プラットフォームへの非公式な移植版が存在する(FreeBSD[4]NetBSD[5] など)。

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

開発者[編集]

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

参考文献[編集]

脚注[編集]

外部リンク[編集]