C++で関数呼出しを視覚化 コールグラフを出力してみよう

Graphvizによるファンクション・コールの視覚化」を参考に、今開発中の Scheme インタプリタコールグラフを出力してみた。

pvtrace のインストール

http://www.mtjones.com/developerworks/pvtrace.zip
大きめの trace をしたいのであらかじめいくつかソースを書き換える。

symbols.h
#define MAX_FUNCTIONS		2000 // 元は 200 だった
stack.c
#define MAX_ELEMENTS	50000 // 元は 500 だった
インストール
$ make
$ sudo make install

graphviz のインストール

$ sudo apt-get install graphviz

ターゲットのコンパイル

今回は Schemeインタプリタがターゲット。
CXXFLAGS/CFLAGS に -finstrument-functions を追加。
pvtrace に付属している instrument.c をコンパイル/リンク。

実行

インタプリタを実行して終了。

$ ./scheme
mona:/> (print "higepon")
mona:/> (exit)

trace.txt がカレントディレクトリに出来る。

pvtrace 実行

$ pvtrace ./scheme

graph.dot が出力される。
これを graphviz に喰わせれば出力されるのだけど C++ のシンボルが

_GLOBAL__I__ZN6monash5Macro5errorE [shape=rectangle]

と見にくいので c++filt でデマングルしてやる。

デマングル

ただデマングルするだけだとシンボルに半角スペースなどが入って graphviz にうまく認識してもらえないのでクォートもしてやる。
汚いけど Perl ならば

while (<>) {
    my $text = $_;
    $text =~ s/(\_[^\s]+)/my $h = `c++filt $1`; chomp($h);'"' . $h . '"';/eg;
    print $text;
}

みたいな感じ。

出力

dot -Tjpg graph.dot -o graph.jpg

11.3MBの jpg ファイルが出力された。
全部は載せられないので一部だけ。
眺めているといろいろなことが分かる。