Valgrind Memcheck ツールを使用したメモリリーク検出の実践方法

概要

Valgrind は、バイナリ動的インタプリテーション技術に基づいた実行時分析用のツールフレームワークです。プロファイリングやデバッグ機能を備えており、特にメモリ管理の不整合を検出するmemcheckツールが中心的な役割を果たします。

インストーレーション

ソースコードを取得し、ローカルのディレクトリへビルドします。

# アーカイブの取得
wget https://sourceware.org/pub/valgrind/valgrind-3.22.0.tar.bz2 --no-check-certificate

# コンパイル用ディレクトリへの移動と設定
tar xf valgrind-3.22.0.tar.bz2 && cd valgrind-3.22.0
./configure --prefix=./install_prefix

# システムの CPU コア数に合わせて並列ビルドを実行
make -j$(nproc) && make install
前提条件: バージョン互換性の観点から、Red Hat Enterprise Linux 7 以上の環境での動作を推奨します。それ以前のバージョンでは、socket 系のエラーコードが返るなど予期せぬ挙動が生じる可能性があります。

環境変数の設定

作成された実行ファイルをパスに通すことで、コマンドラインから利用可能です。

VG_ROOT="/path/to/install_prefix/bin"
export PATH="${VG_ROOT}:$PATH"

診断コマンドの実行

評価対象のプロバイダに対して、詳細なメモリアラートを取得する場合は以下のように実行します。

valgrind \
  --tool=memcheck \
  --trace-children=yes \
  --leak-check=full \
  --log-file=vg_result.log \
  ./app_executable
  • --tool: 使用する Valgrind のサブツールを指定(ここでは memcheck)。
  • --leak-check: メモリリークの詳細レポートを有効化。
  • --trace-children: 派生した子プロセスも追跡対象とする。
  • --log-file: 出力結果の保存先を定義。

ログ出力の解釈

ログファイルには、アプリケーションのメモリ状態と検出された問題点が記録されます。

ヒープサマリー

==21045== HEAP SUMMARY:
==21045==     in use at exit: 35,163,487 bytes in 13 blocks
==21045==   total heap usage: 2,017 allocs, 2,004 frees, 180,650,623 bytes allocated

実行終了時点で確保されたままのメモリ総量と、通算のアロケート・フリーズ回数が表示されます。

リーク判定カテゴリ

==21045== LEAK SUMMARY:
==21045==    definitely lost: 72 bytes in 3 blocks
==21045==    indirectly lost: 0 bytes in 0 blocks
==21045==      possibly lost: 32,637,056 bytes in 2 blocks
==21045==    still reachable: 2,526,359 bytes in 8 blocks

ここでの重要度は以下の通りです:

  1. definitely lost: ポインタが失われた完全なリーク。
  2. possibly lost: スコープ内からの参照のみで、内部ポインタにより保持されている可能性。
  3. still reachable: 終了まで生存していたが、明示的に解放されなかったメモリ。

未初期化アクセスの警告

特定の分岐処理やソケット通信において、初期化済みでないデータを利用しようとした際の警告例です。

==21046== Conditional jump or move depends on uninitialised value(s)
==21046==    at 0x91FA4C: heartbeat(...) (service.cpp:2349)
==21046== Syscall param socketcall.sendto(msg) points to uninitialised byte(s)

ランタイム上の注意点

大量のスレッドを扱う高性能アプリケーションを対象とする場合、valgrind のメインターゲットプロセスへの負荷が高く、解析中に単一コアの CPU 利用率が飽和する現象が確認されています。これに対し、テスト対象のアプリ自体のリソース使用量は相対的に低下するため、パフォーマンス計測の際はオーバーヘッドを考慮した設計が必要となります。

タグ: valgrind memcheck memory-leak-detection cpp linux-debugging

8月14日 09:33 投稿