18

Linux カーネルのコール グラフを静的に生成するツールを探しています (特定のカーネル構成に対して)。生成されたコール グラフは、すべての呼び出しが含まれているという意味で「完全」である必要があります。これには、Linux カーネルの場合、関数ポインターを使用してのみ行われると想定できる潜在的な間接的なものも含まれます。

たとえば、関数ポインターの型を分析することでこれを行うことができます。このアプローチでは、グラフに不要なエッジが発生しますが、私にとっては問題ありません。

nccはこのアイデアを実装しているようですが、3.0 カーネルで動作させることに成功しませんでした。他の提案はありますか?

このアプローチは、関数ポインターのキャストが使用されている場合にもエッジの欠落につながる可能性があると推測しているため、これが Linux カーネルで発生する可能性があるかどうかも知りたいと思います。

補足として、ソースのセマンティック分析を実行して潜在的なポインター値を推測できるツールは他にもあるようですが、AFAICT では、Linux カーネルなどのプロジェクトで使用するように設計されたものはありません。

どんな助けでも大歓迎です。

4

1 に答える 1

5

2600 万行 (18,000 コンパイル ユニット) のモノリシック C システムのグローバル ポイントツー分析 (間接関数ポインターを使用) と完全なコール グラフの構築を行いました。

これは、DMS ソフトウェア リエンジニアリング ツールキット、そのC フロント エンド、および関連するフロー分析機構を使用して行いました。分析機構 (およびその他の分析) へのポイントは保守的です。はい、いくつかの偽のポイントを取得するため、結果としてエッジを呼び出します。これらを避けるのはかなり難しいです。主要な機能に関する特定の重要な事実を提供し、「組み込みシステム [および OS] はコール グラフにサイクルを持たない傾向がある」などの知識を利用することで、そのようなアナライザーを支援できます。つまり、これらのいくつかを排除できます。もちろん、例外を許容する必要があります。私のモラルは、「大きなシステムでは、すべてが起こる」ということです。

特定の問題には、この特定のソフトウェアに固有の特別なロード スキームを使用して動的にロードされた (!) C モジュールが含まれていましたが、それが問題に追加されました。

関数ポインターのキャストはエッジを失うべきではありません。保守的な分析では、キャスト ポインターが、キャストされた結果に対応するシグネチャを持つシステム内の任意の関数と一致すると単純に想定する必要があります。さらに問題なのは、ある種の互換性のある署名を生成するキャストです。呼び出される実際の関数が int を受け入れるときに関数ポインターを void* foo(uint) にキャストすると、分析のポイントは必然的に間違った関数を保守的に選択します。それをアナライザーのせいにすることはできません。キャストはその場合にあります。はい、2600万回線システムでこの種のゴミを見ました。

これは確かに Linux を分析するのに適切な規模です (これはわずか 800 万行程度だと思います :-)。ただし、特に Linux で試したことはありません。

このツールのセットアップは、コンパイル自体、特に生成する Linux カーネルの構成に関するすべての詳細を取得する必要があるため、複雑です。そのため、コマンド ライン スイッチなどを取得するには、コンパイラの呼び出しをインターセプトする必要があります。

于 2012-02-27T22:20:55.613 に答える