mcpField
D
dwarf-expert

dwarf-expert

github.com/trailofbits開発7.9k5.3k 回インストール今日更新
リポジトリ

dwarf-expert について

dwarf-expertは、DWARFデバッグ情報を扱う技術スキルです。検索や検証、パーサー作成に必要な資料とツールの使い方を開発者に案内し、実行時デバッグは対象外です。

主な機能

  1. 01名前やアドレスによるDIE検索
  2. 02DWARF構造と品質の検証
  3. 03DWARF形式の詳細解説
  4. 04解析ライブラリの紹介
  5. 05パーサーの注意点の提示

活用シーン

  1. 01デバッグ情報からシンボルや項目を検索
  2. 02コンパイル後のデバッグ情報を検査
  3. 03バイナリで起きるデバッガーの問題を調査
  4. 04DWARF解析コードの作成やレビュー

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/trailofbits/skills --skill dwarf-expert

インストール後、Claude Code で/dwarf-expertを入力して読み込まれたか確認します。

同梱ファイルagents/openai.yamlassets/trail-of-bits-mark.svg

詳細

DWARF エキスパート

DWARF デバッグ情報の専門知識:解析と検索、整合性の検証、標準に関する質問への回答、およびそれを利用するコードの作成ができます。対象外:実行時デバッグ(gdb/lldb を使用)、DWARF セクションを超えるリバースエンジニアリング(Ghidra/IDA を使用)、コンパイラー固有の DWARF 生成バグ。

信頼できる情報源

正確さが重要な場合は、記憶に頼らず標準の詳細を調べてください。

  1. dwarfstd.org — 公式仕様です。たとえば「DWARF5 DW_TAG_subprogram attributes site:dwarfstd.org」のように、特定のセクションをウェブ検索してください。
  2. LLVM — llvm/lib/DebugInfo/DWARF/ は信頼できるリファレンス実装です。DWARFDie.cpp(DIE と属性へのアクセス)、DWARFUnit.cpp(コンパイル単位)、DWARFDebugLine.cpp(行テーブル)、DWARFVerifier.cpp(検証)を参照してください。
  3. libdwarf — github.com/davea42/libdwarf-code にある、C 言語によるリファレンス実装です。

dwarfdump による解析と検索

DWARF 固有の作業では、readelf より dwarfdump を優先してください。実装は libdwarf の dwarfdump と LLVM の llvm-dwarfdump の 2 種類があり、オプションも異なります。また、単に dwarfdump と入力した場合はどちらが実行されるか分からないため、まず dwarfdump --version で確認してください。以下のオプションは LLVM のものです。

macOS では、リンク済みの Mach-O 実行ファイルに DWARF は含まれません。dsymutil が DWARF を収集して .dSYM バンドルに格納するまで、DWARF は .o ファイル内に残ります。実行ファイルではなく、dSYM(またはオブジェクトファイル)を dwarfdump に指定してください。pyelftools は ELF 専用です。Mach-O をスクリプトで扱う場合は、LLVM ツールを使用してください。

  • --all:すべての DWARF セクションをダンプします。--debug-info、--debug-line などは、それぞれ単一のセクションをダンプします
  • --show-children [--recurse-depth=<n>]:選択したエントリーを出力する際に子 DIE を含めます。パラメーター、ローカル変数、構造体メンバーは、関数および型 DIE の子です
  • --show-parents [--parent-recurse-depth=<n>]:親 DIE を含めます
  • --show-form:エンコーディングの詳細が必要な場合に、属性の form 型を出力します
  • --find=<name>:アクセラレーターテーブルを使った完全一致の名前検索です。高速ですが網羅的ではありません。一致しない場合は --name を使用してください
  • --name=<pattern> [--ignore-case] [--regex]:DIE 名を網羅的に検索します
  • --lookup=<address>:アドレスをカバーする DIE を検索します
  • --verbose:低レベルのエンコーディング詳細を出力します

DIE の検索

クエリーが複雑になるにつれて、次の方法を順に試してください。

  1. 名前またはアドレスで一致:まず --find、次に --name を使用します。アドレスには --lookup を使用します。
  2. 属性または型のクエリー(たとえば、型が float * のすべてのパラメーター):ダンプして絞り込みます。grep -B を使うと、各 DIE のオフセットを含むヘッダー行を取得できます。 llvm-dwarfdump file | grep -B 5 "float \*" | grep DW_TAG_formal_parameter 次に、各 DIE のオフセットを指定して --debug-info=<offset> --show-children で出力します(--lookup が受け取るのはプログラムアドレスであり、DIE オフセットではありません)。
  3. 複数属性または構造に関するクエリー:grep のパイプラインが扱いにくくなったら、pyelftools を使った Python スクリプトを作成してください。

DWARF の整合性を検証する

  • llvm-dwarfdump --verify <binary>:構造を検査します(ユニットチェーン、DIE の関係、アドレス範囲)。--error-display=<quiet|summary|details|full> で詳細レベルを制御し、--verify-json=<path> で機械可読なエラー概要を出力します。終了コードのみを確認する場合は --quiet を指定します。
  • llvm-dwarfdump --statistics <binary>:デバッグ情報の品質指標を JSON 形式で出力します。コンパイラのバージョンや最適化レベルをまたいで比較し、リグレッションを検出できます。

DWARF を生成した後(コンパイラ、バイナリ書き換えツール)、バイナリでデバッガーが正しく動作しない場合、または既知の正常なファイルを使って DWARF ツールを開発する場合に検証してください。

現行世代のコンパイラが古いバージョンの DWARF を出力した場合、ビルド時に -gdwarf-N が明示的に渡されています。最近の gcc と clang のデフォルトは v4/v5 なので、ツールチェーンのデフォルトを前提にせず、ビルドシステムを確認してください。GCC は DW_AT_producer にフラグを埋め込むため、その指定は多くの場合そこから読み取れます。clang の producer 文字列にはフラグが含まれません。古いバージョンは今でも広く使われており、表現上の違いを除けば同じ方法で読み取れます。v2 の出力では、メンバーのオフセットがロケーション式(DW_OP_plus_uconst)として、リンケージ名が DW_AT_MIPS_linkage_name として現れます。

readelf

一般的な ELF 構造を調べる場合や、dwarfdump が利用できない場合に使用します。

  • --debug-dump=<section>:DWARF セクション(info、line など)をダンプします
  • --dwarf-depth=<n> / --dwarf-start=<n>:DIE の深さ/開始オフセットを制限します

DWARF を解析するコードを書く

手作業で解析するより、既存のライブラリを優先してください。

ライブラリ言語備考
libdwarfC/C++github.com/davea42/libdwarf-code — 低レベルのライブラリで、dwarfdump の実装に使用されています
pyelftoolsPythongithub.com/eliben/pyelftools — ELF 全般の解析にも対応しています
gimliRustgithub.com/gimli-rs/gimli — コンテナファイルを読み込むには object と組み合わせます
debug/dwarfGo標準ライブラリ
LibObjectFile.NETgithub.com/xoofx/LibObjectFile — ELF/PE オブジェクトファイルにも対応しています

特別な事情がない限り、単発のスクリプトには pyelftools を使う Python を標準としてください。

DWARF 固有の注意点です。DWARF コードをレビューするときにも確認してください。

  • 属性は省略可能です。DIE に DW_AT_name、DW_AT_type、範囲などが含まれない場合があります。
  • 属性の間接参照:DIE の属性は、DW_AT_abstract_origin(インライン化されたインスタンス)または DW_AT_specification(アウトオブライン定義)が参照する DIE に存在する場合があります。データがないと判断する前に、参照チェーンを解決してください。
  • 型チェーン:修飾子や修飾型(DW_TAG_const_type、DW_TAG_pointer_type など)は基底の型をラップします。基底型に到達するまで DW_AT_type のリンクをたどってください。

コメント