ohos-dev-distributed-cpp-callgraph-analysis について
OpenHarmonyのC++コールチェーンとデータ伝播経路の網羅性を調べるスキルです。LSPやソースの証拠、エッジ分類、カバレッジ表を組み合わせ、補助スクリプトの出力だけでは完全性を断定しません。
主な機能
- 01エントリーポイント・動作・範囲の定義
- 02LSP・ソース・ビルド情報によるエッジ探索
- 03直接・仮想・コールバック・IPC等の分類
- 04証拠をコールチェーン表で管理
- 05コード各面の変更カバレッジ確認
- 06任意の成果物解析による候補探索
活用シーン
- 01OpenHarmonyサブシステム間のフィールド追跡
- 02変更が関連するコールパス全体に届くかの評価
- 03未解決のコールバック・IPC・動的ロード経路の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ openharmonyinsight/ openharmony-skills --skill ohos-dev-distributed-cpp-callgraph-analysisインストール後、Claude Code で/ohos-dev-distributed-cpp-callgraph-analysisを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
ohos_callgraph.pyREADME.mdevals/evals.jsonREADME.mdreferences/lsp-bootstrap.mdscripts/setup_lsp.pytests/test_ohos_callgraph.pytest_setup_lsp.py詳細
OpenHarmony の呼び出しチェーン完全性分析
このスキルには、1 つの判断レイヤーと、任意で使用するツールサポートがあります。
- エージェントのワークフロー:呼び出しチェーンの完全性を判断できる唯一のレイヤーです。LSP/ソースのエビデンス、エッジの分類、カバレッジマトリックスを使用します。
- 任意のアーティファクトによるフォールバック:
ohos_callgraph.pyは、LSP/ソースのエビデンスに不足がある場合、または LSP が利用できない場合に、ビルドアーティファクトから直接呼び出しエッジの候補と、ベストエフォートの vtable/dlopen ヒントを検出します。
スクリプトの出力だけを根拠に、呼び出しチェーンが完全だと主張してはいけません。
リポジトリに対応した LSP のセットアップ
分析の前に、正しい OpenHarmony 製品のコンパイルコンテキストに基づく、動作中の LSP/MCP ツールがすでにあるか確認します。利用できる場合は、それを使用してください。
LSP がない場合、またはリポジトリを正しく解決できない場合は、分析の前に
references/lsp-bootstrap.md を読み、手順に従ってください。セットアップは任意のサポートであり、前提条件ではありません。セットアップまたはスモークテストに失敗した場合は、LSP を利用不可/不完全として記録し、ソース、ビルド、シンボル、ヘルパー、ランタイムのエビデンスを使って続行してください。
特定のファイルで clangd が極端に遅い場合(CPU 使用率 100% の状態が数分続く場合)、そのファイルはフィルタリング後の compile_commands.json に含まれていない可能性があります。Claude クライアントでは、セットアップ時に --install-hook を渡し、Claude PreToolUse の自動修正フックをインストールしてください。Codex またはその他のクライアントでは、
references/lsp-bootstrap.md の「File Not in compile_commands.json」セクションに記載されている手動修正を使用してください。
必須のワークフロー
1. 分析対象を定義する
ツールを使用する前に、次の内容を明示します。
OnRemoteRequest、HandleEvent、またはサブシステム固有のエントリ関数などのエントリポイントまたはイベントパス。- 伝播されるフィールド、ルーティングの判断、状態遷移などの対象データまたは動作。
- 含めるスコープの境界:クライアント/サーバー、IPC、コールバック、仮想インターフェース、dlopen/dlsym の実装、生成コード、テスト。
- 意図的に除外するスコープの境界と、その理由。
これらのいずれかが不明な場合は、まずコードを調査し、範囲を限定した仮定を置いてください。この手順を省略してはいけません。
2. 候補エッジを検出する
次の順序でエビデンスを使用します。
- LSP/clangd:定義、宣言、参照、呼び出し階層、オーバーライド候補、マクロを考慮したシンボル位置を調べるための、推奨される静的ソースです。
- ソース検索:トランザクションコード、リスナー登録、
LoadLibrary<>、dlsym、生成ファイル名など、LSP が適切にモデル化しないフレームワークのパターンをrgで検索します。 - ビルドグラフとシンボルツール:GN/Ninja、
llvm-nm、llvm-readelf、llvm-objdump、llvm-cxxfiltを使用して、ライブラリ、エクスポート、リンクエッジ、生成アーティファクトを調べます。 - ヘルパースクリプト(必要な場合のみ):LSP/ソース/ビルドのエビデンスだけでは説明できないエッジが残る場合、アーティファクトレベルでの確認が有用な場合、または LSP が利用不可/不完全な場合に、
ohos_callgraph.pyを使用して IR レベルの直接エッジ候補と、ベストエフォートの vtable/dlopen ヒントを検出します。 - ランタイムトレース:仮想関数、コールバック、IPC、dlopen/dlsym のエッジを静的エビデンスで一意に解決できない場合は、ログ、インストルメンテーション、またはシンボル化されたトレースを使用します。
言語レベルの C++ の事実を調べる場合は LSP が第一選択ですが、ランタイムバインディングや OpenHarmony のフレームワークプロトコルを調べるには不十分です。
LSP/clangd を利用できる場合は、次の項目の主要な調査手段として使用してください。
definition/declarationreferencescall hierarchyの呼び出し元/呼び出し先- オーバーライドおよび実装の候補
- マクロ展開後のシンボル位置
LSP による直接呼び出しの結果を重複して得るだけの目的で、ヘルパースクリプトを実行してはいけません。「コンパイル済みアーティファクトに候補エッジが含まれているか」「LSP でこのパスを解決できない場合、どの候補が存在するか」など、異なる問いに答えられる場合にのみ実行してください。
LSP が利用不可または不完全な場合は、エビデンステーブルにその旨を記載し、ソース検索とビルド/シンボルのエビデンスにフォールバックしてください。
ヘルパースクリプト
リソースの確認:ヘルパーを実行する前に、find <obj_dir> -name '*.o' | grep <repo-filter> | wc -l を使ってビットコードファイルの数を見積もってください。件数が約200ファイルを超える場合は、--repo フィルターを絞り込むか、代わりにLSP/ソースの証拠を使用してください。各ファイルでLLVMツールを2回実行する必要があり(各回約1~2秒)、200ファイルでは5~10分かかることがあります。
必須のヘルパー呼び出し形式です。エージェントはスクリプトを呼び出す前にソースツリーとリポジトリフィルターを解決し、それらを明示的に渡す必要があります。
SCRIPT=/path/to/skills/ohos-dev-distributed-cpp-callgraph-analysis/ohos_callgraph.py
python3 "$SCRIPT" <entry-function> \
--oh-root <openharmony-source-root> \
--product <product-name> \
--repo <repo-filter> \
--depth 4 \
--skip-prefix "Subsystem::LogHelper" --skip-prefix "Subsystem::TimeUtil"
組み込みのデフォルト(HiLog、std::__h:: など)を使用するには、--skip-prefix を省略してください。サブシステム固有のプレフィックスでデフォルトを完全に上書きするには、--skip-prefix を1つ以上指定してください。
直接の呼び出し元を逆引きします。
python3 "$SCRIPT" <target-function> \
--oh-root <openharmony-source-root> \
--product <product-name> \
--repo <repo-filter> \
--reverse \
--depth 3
ヘルパースクリプトの出力は候補リストです。重要なエッジはすべて、引き続きソースの証拠で裏付ける必要があります。 逆引きモードでは、ヘルパースクリプトは直接の呼び出しエッジのみを逆引きします。vtableまたはdlopen/dlsymのヒントエッジは逆引きしません。
3. すべてのエッジを分類する
各呼び出しチェーンのエッジを分類する必要があります。
| 種類 | 必要な証拠 |
|---|---|
direct | LSPの呼び出し階層/参照を優先し、呼び出し元の行と呼び出し先の定義または宣言を含める |
virtual | LSPのオーバーライド候補を優先し、インターフェースの呼び出し箇所、候補となるオーバーライド、判明している場合はディスパッチの理由を含める |
callback | 登録箇所と呼び出し箇所を含める。LSPでシンボルの位置は特定できますが、通常、登録から呼び出しまでのフローは証明できません |
ipc | プロキシの書き込み、スタブの読み取り、トランザクションコード、サービスハンドラーを含める |
dlopen/dlsym | ロード箇所、ライブラリ/シンボル名、ファクトリーまたは関数ポインターの使用箇所を含める。必要に応じてシンボルまたはトレースで確認する |
macro/generated | マクロに対応したLSPの位置情報を優先し、エッジを証明する生成ソースまたは展開先を含める |
unknown | 証拠が不足しており、完全性を主張できません |
virtual、callback、ipc、dlopen/dlsym の各エッジについては、関連する候補をすべて列挙するか、候補が1つだけに該当する理由を明示してください。
4. 証拠テーブルを作成する
次の列を持つテーブルを出力してください。
| 呼び出し元 | 呼び出し先/候補 | エッジの種類 | 証拠のソース | 証拠 | 信頼度 | 変更が必要な理由 | 変更状況 |
|---|
ルール:
証拠のソースはlsp、source、build、symbol、script、runtime、manualのいずれか1つ以上です。証拠にはファイルパスと行番号を含める必要があります。信頼度はconfirmed、candidate、unknownのいずれかです。変更が必要な理由には、対象のデータまたは動作がこのエッジを通る必要がある理由を説明します。変更状況はdone、missing、not needed、unknownのいずれかです。scriptの証拠だけでは、非直接エッジをconfirmedにできません。
複数のエッジの種類を1行にまとめないでください。
5. 変更カバレッジマトリクスを作成する
データ伝播に関する変更(例:複数のレイヤーを経由して引き渡す必要があるフィールド)では、該当する各項目を確認します。
| 項目 | 確認内容 | 静的な証拠 | 実行時の証拠 | 状態 |
|---|---|---|---|---|
| 関数シグネチャ | パラメーターまたはオブジェクトが対象データを保持している | LSP の定義/宣言、またはソース行 | 任意 | |
| 呼び出し引数 | 呼び出し元がデフォルト値や古い値ではなく、正しい値を渡している | LSP の呼び出し階層/参照、またはソース行 | 任意 | |
| イベント/オブジェクトのフィールド | フィールドが正しく設定、コピー、複製、リセットされている | ソース/LSP のフィールド参照 | 任意 | |
| IPC プロキシ/スタブ | Parcel の書き込み/読み取り順序とトランザクションの互換性 | ソースのトランザクションと Parcel の証拠 | 不明瞭な場合はトレース/ログ | |
| サービスのディスパッチ | サーバー側が値を受け取り、使用している | ソース/LSP のハンドラーパス | 不明瞭な場合はトレース/ログ | |
| 仮想関数のオーバーライド | 到達可能なすべてのオーバーライドが値を受け取るか、導出している | LSP のオーバーライド候補とソースの証拠 | 静的ディスパッチだけでは一意に特定できない場合は必須 | |
| コールバックフロー | 登録と呼び出しの両方で値が保持されている | ソースの登録/呼び出しの証拠 | 登録から呼び出しまでのフローが不明瞭な場合は必須 | |
| dlopen/dlsym の実装 | 読み込まれた実装が値を処理している | ソースとシンボル/ビルドの証拠 | 読み込み先が実行時に決まる場合は必須 | |
| 生成コード | 生成されたラッパーと ABI レイヤーで値が保持されている | 生成されたソースまたはビルド成果物の証拠 | 任意 | |
| テスト | 単体/システムテストで、代表的な経路と境界の少なくとも 1 つを検証している | テストソースの証拠 | 利用可能な場合はテスト実行結果 |
最終回答では、どの行が完了、未対応、不明なのかを明記してください。
6. 完全性を判断する
次のラベルを使用します。
- Complete:関連する確認済みエッジと候補エッジがすべて
doneまたはnot neededであり、不明点が解決済み、または明示的に対象外です。 - Incomplete:必須のエッジまたは項目が 1 つ以上
missingです。 - Not provable:重要なエッジが
unknownのままであるか、結論に影響する実行時依存のエッジを静的な証拠だけでは解決できません。
ヘルパースクリプトの適用範囲
ohos_callgraph.py は、LSP/ソースの調査後に任意で使用できる成果物の代替手段です。
opt --print-callgraphによる直接的な IR 呼び出しエッジ- LLVM IR メタデータによるベストエフォートの vtable インターフェースのヒント
- 一般的な
LoadLibrary<>/CreateInstanceパターンによるベストエフォートの dlopen ヒント - 直接呼び出し元のみを逆引きします。逆引きモードには vtable または dlopen/dlsym のヒントエッジは含まれません。
制限事項:
- C++ の呼び出しをすべて証明するものではありません。
- 実行時の仮想ディスパッチを一意のオーバーライドに解決するものではありません。
- コールバック、関数ポインター、または
std::functionの対象を証明するものではありません。 - IPC パラメーターの伝播を証明するものではありません。
- フィールドの伝播を証明するものではありません。
--name-keywordは、粗いヒントとしてデマングルされた関数名と直接の子関数名だけを確認します。C++ のパラメーター名、呼び出し引数、メンバーアクセス、ローカル変数、IPC のシリアライズは調べません。 - ビルド成果物が古い場合、ビットコードが欠落している場合、最適化方法が異なる場合、または外部ツールが失敗した場合、エッジを検出できないことがあります。
証拠ワークフローでは、ヘルパースクリプトを候補の発見を補助する目的に限って使用してください。LSP/ソースの証拠で関連する直接呼び出しがすでに網羅されており、成果物レベルでの確認が不要な場合は、スクリプトを実行しないでください。
LSP に関するガイダンス
レビュー対象の OpenHarmony 製品に適したコンパイルコンテキストに基づいている場合は、LSP/clangd を根拠として使用してください。リポジトリに compile_commands.json がない場合、または clangd がインクルードやマクロを解決できない場合は、LSP の根拠を不完全とし、代わりにソースやビルドの根拠を使用してください。
LSP を利用できず、環境がセットアップに対応している場合は、フォールバックする前にリポジトリ単位の LSP のセットアップに従ってください。リポジトリ単位のデータベースを生成できる場合は、製品全体のコンパイルデータベースを直接使用しないでください。製品のデータベースは数ギガバイトになることがあり、不要なインデックス作成コストが発生します。
LSP を活用した確認方法として、次を推奨します。
- 直接の関数呼び出しについては、呼び出し箇所から発信側の呼び出し階層または定義への移動を使い、その後、呼び出し元と呼び出し先のファイル行を記録します。
- 逆方向の解析では、着信側の呼び出し階層と参照を使用し、その後、呼び出し箇所を手作業で検証します。
- 仮想関数呼び出しについては、実装/オーバーライドのクエリを使用して候補を列挙します。構築/登録/ソース上の規則または実行時トレースによって実際のターゲットが証明されない限り、候補は
candidateのままにします。 - マクロについては、LSP で解決されたシンボルの場所を使用し、該当する場合はマクロまたは生成された展開元を記録します。
コールバックのフロー、IPC ディスパッチ、または dlopen/dlsym のターゲットを確認する際に、LSP だけに頼らないでください。
最終回答の必須形式
このスキルを使用する場合は、最後に次の内容を含めます。
- 対象範囲:エントリーポイント、対象となるデータ/動作、含まれる境界。
- 根拠の表:エッジごとの根拠の情報源、根拠、確度、ステータス。
- カバレッジマトリックス:変更対象の各箇所について、静的な根拠、実行時の根拠、ステータス。
- 結論:
Complete、Incomplete、Not provableのいずれかと、正確に不足している項目または不明な項目。
必須の境界を調査できない場合は、その旨を明記し、unknown とします。
例:MMI サブシステム
マルチモーダル入力(MMI)サブシステムの解析では、一般的な対象として次が挙げられます。
- エントリーポイント:
HandleMouseEvent、UpdateMouseTarget、OnRemoteRequest - 伝播するフィールド:
groupId、displayId、ポインターのターゲットルーティング、デバイスバインディング - スキップするプレフィックス:
OHOS::MMI::FormatLog、OHOS::MMI::GetSysClockTime、OHOS::MMI::InnerFunction(--skip-prefixで渡します) - 主要な境界:
MultimodalInputConnectStubを介したクライアント/サーバー IPC、EventDispatchHandlerのコールバックチェーン、InputDeviceManagerによる dlopen ロード