valgrind について
Valgrind によるメモリエラー検出と、キャッシュ、コールグラフ、ヒープ使用量の分析をエージェント向けに案内します。Memcheck のレポート解釈、抑制設定、コマンド例も含みます。
主な機能
- 01Memcheck によるメモリエラー検出
- 02リークと未初期化値の分析
- 03Cachegrind によるキャッシュシミュレーション
- 04Callgrind によるコールグラフ分析
- 05Massif によるヒープ分析
活用シーン
- 01リークや無効なメモリアクセスの調査
- 02perf を使わないキャッシュ動作の分析
- 03呼び出しコストとヒープピークの特定
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mohitmishra786/ low-level-dev-skills --skill valgrindインストール後、Claude Code で/valgrindを入力して読み込まれたか確認します。
同梱ファイルreferences/valgrind-vs-asan.md
詳細
Valgrind
目的
Valgrind のツールについて、エージェントをガイドします。メモリエラーには Memcheck、キャッシュシミュレーションには Cachegrind、コールグラフには Callgrind、ヒーププロファイリングには Massif を使用します。
トリガー
- 「プログラムでメモリリーク/解放後使用が発生します」
- 「ASan を使えません。代わりに Valgrind を使えますか?」
- 「perf を使わずにキャッシュの動作をプロファイリングするにはどうすればよいですか?」
- 「Callgrind でコールグラフを可視化するにはどうすればよいですか?」
- 「ヒープ割り当てのパターンをプロファイリングするにはどうすればよいですか?」
- 「Valgrind が、修正できないサードパーティコードのエラーを報告します」
ワークフロー
1. Memcheck — メモリエラーの検出
最良の結果を得るには、-g -O1 を付けてコンパイルします。-O0 でも問題ありません。誤検出が発生する可能性があるため、-O2 以上は避けてください。
valgrind --tool=memcheck \
--leak-check=full \
--show-leak-kinds=all \
--track-origins=yes \
--error-exitcode=1 \
./prog [args]
主なフラグ:
| フラグ | デフォルト | 効果 |
|---|---|---|
--leak-check=full | summary | リークの詳細をすべて表示します |
--show-leak-kinds=all | definite | すべての種類のリークを表示します |
--track-origins=yes | no | 未初期化の値の由来を表示します(低速) |
--error-exitcode=N | 0 | エラーが見つかった場合に N で終了します(CI 連携) |
--log-file=file | stderr | レポートをファイルに保存します |
--suppressions=file | none | 既知の誤検出を抑制します |
--gen-suppressions=yes | no | エラーに対する抑制設定を出力します |
--max-stackframe=N | 2000000 | スタックが深い場合に値を大きくします |
--malloc-fill=0xAB | off | 割り当てたメモリを埋めます(未初期化メモリの使用を検出) |
--free-fill=0xCD | off | 解放したメモリを埋めます(解放後使用を検出) |
2. Memcheck の出力を理解する
==12345== Invalid read of size 4
==12345== at 0x4007A2: foo (main.c:15)
==12345== by 0x400846: main (main.c:30)
==12345== Address 0x5204040 is 0 bytes after a block of size 40 alloc'd
==12345== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck.so)
==12345== by 0x40074B: main (main.c:25)
- 不正な読み取り/書き込み:範囲外アクセスです。配列の境界を確認してください
- 未初期化値の使用:書き込み前に読み取っています。
--track-origins=yesを使用してください - 不正な解放/二重解放:malloc/free の不一致です。所有権を確認してください
- 確実に失われた:ポインターから到達できません。明らかなリークです
- 間接的に失われた:連鎖をたどって失われています。通常、根本にあるリークが 1 つ存在することを意味します
- 失われた可能性がある:ブロックの途中を指している可能性があります。カスタムアロケーターでは誤検出であることがよくあります
3. リークの種類
| 種類 | 意味 |
|---|---|
| 確実に失われた | ブロックへのポインターがありません |
| 間接的に失われた | 別の失われたブロックを介して失われています |
| 失われた可能性がある | ブロックの途中を指すポインターがあります |
| 引き続き到達可能 | 終了時にポインターが存在します。リークではありませんが、解放されていません |
ライブラリコードでは、--show-leak-kinds=definite,indirect を指定すると、引き続き到達可能な領域によるノイズを減らせます。
4. 抑制設定
# Generate suppression for current error
valgrind --gen-suppressions=yes ./prog 2>&1 | grep -A20 '{'
# Example suppression file (valgrind.supp)
{
openssl_uninit
Memcheck:Cond
fun:SHA256_Init
...
}
# Use suppression file
valgrind --suppressions=valgrind.supp ./prog
5. Cachegrind — キャッシュシミュレーション
valgrind --tool=cachegrind ./prog
# Output: cachegrind.out.PID
# Annotate source
cg_annotate cachegrind.out.12345 --auto=yes
# Diff two runs
cg_diff cachegrind.out.before cachegrind.out.after
主な指標:
I1mr/ILmr:L1/LL 命令キャッシュのミス率D1mr/DLmr:L1/LL データ読み取りのミス率D1mw/DLmw:L1/LL データ書き込みのミス率
6. Callgrind — コールグラフのプロファイリング
valgrind --tool=callgrind --callgrind-out-file=callgrind.out ./prog
# Analyse
callgrind_annotate callgrind.out
# Visualise in KCachegrind (GUI)
kcachegrind callgrind.out
Callgrind は perf より低速ですが、root 権限なしで動作し、正確な呼び出し回数を提供します。
7. Massif — ヒープのプロファイリング
valgrind --tool=massif ./prog
# Visualise
ms_print massif.out.PID | less
# GUI
massif-visualizer massif.out.PID
Massif は時間経過に伴うヒープ使用量を表示します。割り当てがピークになる箇所の特定や、徐々に進行するリークの追跡に役立ちます。
8. パフォーマンスに関する考慮事項
Valgrind Memcheck の実行速度は、ネイティブ実行の約 10~50 倍遅くなります。以下の方法で軽減できます。
- 代表的なワークロードを短時間だけ実行します
- CI で早期に失敗させるには、
--error-exitcode=1を使用します - 開発中の高速なメモリチェックには ASan(
-fsanitize=address)を使用します - ASan を使用できない場合(古いツールチェーン、本番環境に近い環境など)に Valgrind を使用します
Valgrind と ASan の比較については、references/valgrind-vs-asan.md を参照してください。
関連スキル
- より高速な ASan/UBSan の代替手段には
skills/runtimes/sanitizersを使用します - CPU レベルのプロファイリングには
skills/profilers/linux-perfを使用します(Cachegrind より高速です) - Callgrind の出力を可視化するには
skills/profilers/flamegraphsを使用します
コメント
Markdown 対応