コードの絵付き関数呼び出しグラフを取得するためのツール

    <リ>

    エジプト (フリーソフトウェア)

    <リ>

    ncc

    <リ>

    KcacheGrind (GPL)

    <リ>

    Graphviz (CPL)

    <リ>

    CodeViz (GPL)


動的分析方法

ここでは、いくつかの動的分析方法について説明します。

動的メソッドは実際にプログラムを実行してコール グラフを決定します。

動的メソッドの反対は静的メソッドで、プログラムを実行せずにソースのみから判断しようとします。

動的メソッドの利点:

  • 関数ポインタと仮想 C++ 呼び出しをキャッチします。これらは重要なソフトウェアに多数存在します。

動的メソッドの欠点:

  • プログラムを実行する必要がありますが、速度が遅いか、持っていないセットアップが必要です。クロスコンパイル
  • 実際に呼び出された関数のみが表示されます。たとえば、コマンドライン引数に応じて、一部の関数が呼び出される場合と呼び出されない場合があります。

KcacheGrind

https://kcachegrind.github.io/html/Home.html

テスト プログラム:

int f2(int i) { return i + 2; }
int f1(int i) { return f2(2) + i + 1; }
int f0(int i) { return f1(1) + f2(2); }
int pointed(int i) { return i; }
int not_called(int i) { return 0; }

int main(int argc, char **argv) {
    int (*f)(int);
    f0(1);
    f1(1);
    f = pointed;
    if (argc == 1)
        f(1);
    if (argc == 2)
        not_called(1);
    return 0;
}

使い方:

sudo apt-get install -y kcachegrind valgrind

# Compile the program as usual, no special flags.
gcc -ggdb3 -O0 -o main -std=c99 main.c

# Generate a callgrind.out.<PID> file.
valgrind --tool=callgrind ./main

# Open a GUI tool to visualize callgrind data.
kcachegrind callgrind.out.1234

これで、多くの興味深いパフォーマンス データを含む素晴らしい GUI プログラム内に取り残されました。

右下にある「コールグラフ」タブを選択します。これは、関数をクリックすると、他のウィンドウのパフォーマンス メトリックに相関するインタラクティブな呼び出しグラフを表示します。

グラフをエクスポートするには、グラフを右クリックして [グラフのエクスポート] を選択します。エクスポートされた PNG は次のようになります:

そこから次のことがわかります:

  • ルート ノードは _start です これは実際の ELF エントリ ポイントであり、glibc 初期化ボイラープレートが含まれています
  • f0f1f2 相互に期待どおりに呼び出されます
  • pointed 関数ポインターで呼び出したにもかかわらず、 も表示されます。コマンドライン引数を渡した場合、呼び出されなかった可能性があります。
  • not_called 追加のコマンド ライン引数を渡さなかったため、実行時に呼び出されなかったため、表示されません。

valgrind のクールなところ 特別なコンパイル オプションは必要ありません。

したがって、ソース コードがなくても、実行可能ファイルだけで使用できます。

valgrind 軽量の「仮想マシン」を介してコードを実行することで、なんとかそれを行うことができます。これにより、ネイティブ実行と比較して実行が非常に遅くなります。

グラフでわかるように、各関数呼び出しに関するタイミング情報も取得されます。これは、呼び出しグラフを表示するだけでなく、プログラムのプロファイリングに使用できます。これは、このセットアップの元のユース ケースである可能性があります。 Linux で C++ コードを実行していますか?

Ubuntu 18.04 でテスト済み。

gcc -finstrument-functions + エトレース

https://github.com/elcritch/etrace

-finstrument-functions コールバックを追加し、etrace は ELF ファイルを解析し、すべてのコールバックを実装します。

残念ながら動作しませんでした:なぜ `-finstrument-functions` が動作しないのですか?

要求された出力の形式は次のとおりです:

\-- main
|   \-- Crumble_make_apple_crumble
|   |   \-- Crumble_buy_stuff
|   |   |   \-- Crumble_buy
|   |   |   \-- Crumble_buy
|   |   |   \-- Crumble_buy
|   |   |   \-- Crumble_buy
|   |   |   \-- Crumble_buy
|   |   \-- Crumble_prepare_apples
|   |   |   \-- Crumble_skin_and_dice
|   |   \-- Crumble_mix
|   |   \-- Crumble_finalize
|   |   |   \-- Crumble_put
|   |   |   \-- Crumble_put
|   |   \-- Crumble_cook
|   |   |   \-- Crumble_put
|   |   |   \-- Crumble_bake

特定のハードウェア トレースのサポート以外ではおそらく最も効率的な方法ですが、コードを再コンパイルする必要があるという欠点があります。


Understanding は、コール グラフの作成に非常に優れています。