GPROF(1)

名称
gprof - 呼び出しグラフに基づくプロファイルデータを表示する

書式
gprof [-abcKlLsuz] [-C count] [-e name] [-E name] [-f name] [-F name] [-k fromname toname] [a.out [a.out.gmon ...]]

解説
gprof ユーティリティは、C や Pascal, Fortran77 の実行プロファイルを生成します。 gprof では、呼び出されたルーチンの実行時間は、呼び出した側の ルーチンに加算されます。 プロファイルデータは、呼び出しグラフプロファイルファイル (call graph profile file) から読み出されます。このファイルは、 cc(1), pc(1), f77(1) に -pg をつけてコンパイル されたプログラムによって生成されます。 -pg をつけると、コンパイラは プロファイル用ライブラリをリンクします。 約束事として、これらのライブラリの名前の後には _p が付きます。つまり、プロファイルされるバージョンの libc.a は libc_p.a であり、コンパイラや隣家に直接ライブラリを指定するときに -lc の代りに -lc_p を使用可能です。 与えられたオブジェクトファイル (デフォルトでは a.out) を読み込んで、そのオブジェクトのシンボルテーブルと 呼び出しグラフプロファイルとを結び付けます。 デフォルトのグラフプロファイルファイルの名前は、 実行形式名にサフィックス .gmon を付けたものです。 2 つ以上のプロファイルファイルが与えられると、 gprof は、それらの情報を合計して出力します。

gprof ユーティリティは、各ルーチンが消費した時間を計算します。 次に、この時間は呼び出しグラフの辺にそって伝播されます。 サイクルが見つかると、サイクルに対する呼び出しが、サイクルの時間を 共有するものとされます。 最初のリストには、関数からの呼び出しグラフ全体の合計時間によって ソートされた関数が表示されています。 各関数のエントリの下には、その関数の呼び出しグラフ での (直接の) 子 (すなわち呼び出された関数名) が表示され、それらの 関数の消費時間がどれくらい親 (つまり呼び出した側の関数) に伝播されているかが 示されています。 同様に、各関数のエントリの上側には、 関数での消費時間が呼び出し元の関数にどのように伝播されているかが 示されています。

サイクル全体とそのメンバのリストを示したエントリが、 サイクルの呼び出し回数や実行時間への各メンバの寄与を含めて表示されます。

次のリストでは、 prof(1) (NetBSD, FreeBSDにはありません) と同様なフラットプロファイル (flat profile) 表示されます。 ここには、関数の合計実行時間や呼び出し回数、 その関数本体のみの実行時間 (ミリ秒またはマイクロ秒)、 その関数本体及びそこから呼び出された関数の実行時間 (ミリ秒またはマイクロ秒)、 が表示されます。

最後に関数名の索引が表示されます。

以下のオプションが利用可能です。

-a  静的に宣言された関数の表示を抑制します。 このオプションが指定されると、静的関数についてのすべての関連する情報 (実行時間、別の関数の呼び出し、他の関数からの呼び出しなど) が、 a.out ファイル中の静的関数の直前に読み込まれるされる関数に含まれることになります。

-b  プロファイル中の各フィールドの説明文を抑制します。

-c  オブジェクトファイルのテキスト空間を調べる発見的な方法を使って、 プログラムの静的呼び出しグラフを見つけます。 静的な呼び出しのみの親と子供は、 呼び出し数 0 として表示されます。 アーキテクチャによっては、本オプションはサポートされていません。

-C count
    count 数以上の関数を含む (呼び出し関係の) サイクルを取り除くために、 切断すべきアーク (呼び出し関係) の最小集合を見つけます。 注意:サイクルを中断するために用いられるアルゴリズムは指数関数的な ものです。そのため、このオプションを指定すると、 gprof を実行するのに非常に長い時間がかかります。

-e name
    ルーチン name とそのすべての子孫 (それらの関数が表示抑制されていない親をほかに 持っていなければ) のグラフプロファイルエントリの表示を抑制 します。2 つ以上の -e を指定することができます。各 -e には 1 つしか name を指定することができません。

-E name
    -e と同様、指定されたルーチン name のグラフプロファイル エントリ表示を抑制します。さらに、プログラムのトータルの時間と計算時間の パーセンテージから name で使われている時間を取り除きます。 (たとえば、 -E mcount -E mcleanup がデフォルトです)

-f name
    指定されたルーチン name とその子孫のグラフプロファイルエントリ のみを表示します。 -f オプションは、複数指定することができます。 各オプション -f には、1 つしか name を指定することができません。

-F name
    -f と同様に、指定されたルーチン name とその子孫のグラフ プロファイルエントリのみを表示します。 プログラムのトータルの時間と計算時間の割合 には、表示されたルーチンの時間のみが使われます。 -F は複数指定することができます。各オプション -F には、1 つしか name を指定することができません。オプション -F は、オプション -E の効果を打ち消します。

-k fromname toname
    fromname から toname への関数呼び出し関係のアークを削除します。 このオプションによって、不必要だと思うサイクルを切断することができます。 オプション -k は、複数指定することができます。各オプション -k には一対のルーチン名 (fromname と toname) しか 指定することができません。

-K  sysctl(3) および kldsym(2) のインタフェースを使用して、 現在実行中のカーネルからシンボル情報を収集します。 これは、 a.out 引数を無視させ、 kld(4) モジュール中のシンボルを使用できるようにします。

-l  呼び出しグラフプロファイルの表示を抑制します。

-L  フラットプロファイルの表示を抑制します。

-s  指定されたすべてのプロファイルファイル中のプロファイル情報の合計 を表すサマリプロファイルファイル gmon.sum が生成されます。 このサマリプロファイルファイルはこのあとの gprof の実行に 対して与えられ (その際にも通常 -s が指定される)、一連の a.out 実行の結果のプロファイルデータの合計を 求めることができます。

-u  C プログラムには見えない名前の関数の表示を抑制します。 ELF オブジェクト形式では、文字 ‘’. を含む名前を意味します。 a.out オブジェクト形式では、文字 ‘_’ で開始しない名前を意味します。 それらの関数に関連する情報は、すぐ低位側のアドレスにある (表示が 抑制されていない) 関数に含まれます。 これにより関数内にあるただのラベルが関数と認識されてしまうのを 防ぐ事ができます。

-z  使用されていないルーチン (呼び出し回数と合計時間が 0 である) を表示します。 -c オプションとともに使うと、一度も呼ばれていないルーチンを発見する事ができます。

関連ファイル
a.out
    テキスト空間と名前リスト。
a.out.gmon
    動的な呼び出しグラフとプロファイル。
gmon.sum
    動的な呼び出しグラフとプロファイルのサマリ。

関連項目
cc(1), profil(2), clocks(7)

An Execution Profiler for Modular Programs, S. Graham, P. Kessler, M. McKusick, Software - Practice and Experience, 13, pp. 671-685, 1983.

gprof: A Call Graph Execution Profiler, S. Graham, P. Kessler, M. McKusick, Proceedings of the SIGPLAN '82 Symposium on Compiler Construction, SIGPLAN Notices, 17, 6, pp. 120-126, June 1982.

歴史
gprof プロファイラは、 4.2BSD から登場しました。

バグ
サンプリングの周期がリストの最初に表示されますが、 統計的な域を出ないものであるかもしれません。 我々は、各関数の実行時間はその関数が消費した時間の合計をその関数の 呼び出し回数で割ったものによって表現されると仮定しています。 したがって、呼び出しグラフの関係にそって関数の親に伝播される時間は、 その関係をたどる回数に直接比例しています。

自身がプロファイルされていない親は、プロファイルしている子供から 伝播される時間を持っており、呼び出しグラフのリストのなかで 自動的に起動されるものとして現れます。しかし、この関数が持つ時間は それ以上伝播されません。 同様に、シグナルを捕捉する関数は、それらがプロファイルされていても、 自動的に起動されるものとして現れます (もう少し複雑な理由がありますが)。 プロファイルルーチンを実行している最中にシグナルを捕捉する 関数が呼出されたとき (この場合はすべてが失われてしまいます) を除いては、 シグナルを捕捉する関数の子供の実行時間は、その親に正しく 伝播されるべきです。

プロファイルされているプログラムは、 グラフプロファイル ファイルにプロファイル情報がセーブされるよう exit(3) を呼ぶか、正常に終了しなければいけません。