C言語のコールグラフ作成のメモ

C言語で書かれたプログラムのコールグラフを作成する方法についてのメモ。

コールグラフとは

Wikipediaのコールグラフの項から定義を拝借。

コールグラフ (マルチグラフとも呼ばれる) とは、コンピュータプログラムサブルーチン同士の呼び出し関係を表現した有向グラフである。

プログラムの解析をしていると、関数の呼び出し関係を視覚的に見たい時がある。そんな時には迷わずコールグラフを描いてみるといい。

静的・動的なコールグラフ

コールグラフには、静的なコールグラフと動的なコールグラフの2通りがある。静的なコールグラフとは、プログラムの実行を伴わずに作成するもの。静的なコールグラフはソースコードのみを解析することで得たり、プログラムをコンパイルする時の情報を使って作成する。コールグラフに存在する関数呼び出しがプログラムを実行したときに起こるかどうかはわからない。

一方、動的なコールグラフは、実際にプログラムを実行したときに起きた関数呼び出しに基づいて作成される。そのため、作成にはプロファイラを用いる。動的なコールグラフにおける関数呼び出しは実際に発生したものであるが、入力に依存する。

解析するときに知りたい情報によってどちらのコールグラフを作るのが望ましいか判断する必要がある。網羅的に関数呼び出しを表現したければ静的なコールグラフを作成するべきだし、とある条件下(入力・環境)におけるプログラムの動作を解析したければ動的なコールグラフを作成するべきだ。また、静的なコールグラフでは大規模になりすぎてみるべきポイントを絞れないといった場合に動的なコールグラフから見て実際に動いてる部分から解析するというアプローチもありだろう。

静的なコールグラフの作成

egyptcodeviz というツールが有名どころなようだ。今回は egypt を用いた。使い方は少し調べれば出てくるから、ほかのサイトを見てもらうとして、自分が使った時に調べた点をいくつかメモしておく。

  • egypt をインストールするときに prefix を変える方法が謎。
  • gcc には -fdump-rtl-expand オプションをつける。
  • 複数のファイルからなるプログラムの場合、.extend ファイルを cat して egypt に与えれば良い。(cat しなくても *.extend みたいな感じでもいいのかもしれないが試していない。)
  • gcc が最適化により関数をインライン化するとコールグラフの結果が変わる。例えば、実際には呼び出されている関数が一度も呼び出されないかのような結果が出力される。ソースコードに忠実なコールグラフを得たければ最適化を無効化するべき。
  • 横向きで出力した方が見やすい気がする。dot で A4 横向きで出力するためには、以下のように指定する。
    -Gsize=11.7,8.3 -Grankdir=LR
  • dot で ps ファイルを出力して、ps2pdf で pdf 化しようとすると、横向きがうまく出力されない。おとなしく dot で -Tpdf を指定して初めから pdf で出力すべき。

動的なコールグラフの作成

こちらも複数ツールがあるようだが今回は gperf2dot.py を利用した。名前に gperf とついているが、gperf だけでなく他のプロファイラの出力も読み取ってくれる。こちらも基本的な使い方はほかのサイトを見てもらうとして、ポイントをメモしておく。

  • gperf2dot.py は縦書き表示に適したように作られているっぽい。A4 縦で出力するためには、dot に以下のように指定する。
    -Gsize=8.3,11.7

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です