Go to main content

マニュアルページ セクション 1: ユーザーコマンド

印刷ビューの終了

更新: 2018年8月8日
 
 

gprof(1)

名前

gprof - コールグラフプロファイルデータの表示

形式

gprof [-abcCDlsVz] [-e function-name] [-E function-name] 
     [-f function-name] [-F function-name] 
     [image-file [profile-file...]] 
     [-n number of functions]

説明

gprof ユーティリティーは、プログラムの実行プロファイルを生成します。呼び出されたルーチンの結果が、各呼び出し元のプロファイルに取り込まれます。プロファイルデータは、cc(1) の –xpg オプションまたはその他のコンパイラの –pg オプションでコンパイルされたプログラムによって作成されたコールグラフプロファイルファイルから、または共有オブジェクトの LD_PROFILE 環境変数を設定することによって作成されたコールグラフプロファイルファイルから取得されます。ld.so.1(1) を参照してください。これらのコンパイラオプションは、プロファイリング用にコンパイルされたライブラリルーチンのバージョンにもリンクされています。実行可能イメージファイル image-file (デフォルトでは a.out) のシンボルテーブルが読み取られ、コールグラフプロファイルファイル profile-file (デフォルトでは gmon.out) と関連付けられます。

最初に、各ルーチンの実行回数がコールグラフの境界に沿って伝播されます。サイクルが検出され、サイクルの時間を共有するためにサイクルへの呼び出しが行われます。最初のリストには、関数が示す時間 (コールグラフの子孫の時間を含む) に従ってソートされた関数が示されます。各関数エントリの下には、コールグラフの (直接の) 子およびそれらの時間がこの関数に伝播されている状況が示されます。関数の上の同様の表示には、この関数の時間およびその子孫の時間がコールグラフの (直接の) 親に伝播されている状況が示されます。

サイクルも表示され、サイクル全体のエントリ、サイクルのメンバーのリスト、時間への寄与、およびサイクルの呼び出し回数が示されます。

次に、prof(1) で生成されるプロファイルと同様のフラットプロファイルが生成されます。このリストには、プログラム内の各関数の合計実行時間および呼び出し回数が時間の多い順で示されています。最後に、インデックスが生成されます。これは、関数名とコールグラフプロファイルのインデックス番号の対応を示します。

MARK マクロを使用したプロファイリングのために、単一の関数がサブ関数に分割されることがあります。prof(7) を参照してください。

量子化エラーに注意してください。標本収集の粒度は示されますが、あくまで統計にすぎません。関数の各実行の時間は、関数の合計時間を関数が呼び出された回数で除算することによって表すことができると想定しています。このため、コールグラフの弧に沿って関数の親に伝播される時間は、弧を遷移した回数に正比例します。

プロファイリング情報を gmon.out ファイルに保存するには、プロファイルされたプログラムは exit(2) を呼び出すか、正常に終了する必要があります。

オプション

サポートしているオプションは、次のとおりです。

–a

静的に宣言された関数の出力を抑制します。このオプションを指定した場合、静的関数に関連するすべての情報 (たとえば、時間の標本、別の関数への呼び出し、別の関数からの呼び出し) は、a.out ファイルの静的関数の直前にロードされた関数に属することになります。

–b

簡略化します。プロファイル内の各フィールドの説明を抑制します。

–c

オブジェクトファイルのテキスト空間を検査する発見的方法によって、プログラムの静的コールグラフを検出します。静的関数のみを持つ親または子は、呼び出し回数 0 で示されます。動的にリンクされた実行可能ファイルの場合、リンクされた共有オブジェクトのテキストセグメントは検査されません。

–C

C++ シンボル名を出力する前に復号化します。

–D

指定されたすべてのプロファイルファイルのプロファイル情報の差異を示すプロファイルファイル gmon.sum を生成します。このサマリープロファイルファイルは、a.out ファイルの複数の実行のプロファイルデータを集約するために、gprof (–D も指定) の後続の実行に渡すことができます。–s オプションも参照してください。

たとえば、プロファイルファイル gmon.sum で関数 A が関数 B を n 回呼び出し、プロファイルファイル gmon.outm 回呼び出すとします。–D を指定すると、A から B の呼び出し回数を n-m として示す新しい gmon.sum ファイルが作成されます。

–efunction-name

ルーチン function-name およびそのすべての子孫 (抑制されていない別の祖先がない場合) のグラフプロファイルエントリの出力を抑制します。–e オプションは複数指定できます。各 –e オプションに指定できる function-name は 1 つのみです。

–Efunction-name

ルーチン function-name (およびその子孫) のグラフプロファイルエントリの出力を抑制します (下の –e と同様)。また、合計時間および時間の割合の計算から function-name (およびその子孫) が費やした時間を除外します。–E オプションは複数指定できます。例:

–E mcount –E mcleanup

はデフォルトです。

–ffunction-name

ルーチン function-name およびその子孫のグラフプロファイルエントリのみを出力します。–f オプションは複数指定できます。各 –f オプションに指定できる function-name は 1 つのみです。

–Ffunction-name

ルーチン function-name およびその子孫のグラフプロファイルエントリを出力します (下の –f と同様)。また、出力されるルーチンの時間のみを合計時間および割合の計算に使用します。–F オプションは複数指定できます。各 –F オプションに指定できる function-name は 1 つのみです。–F オプションは –E オプションをオーバーライドします。

–l

すべてのローカルシンボルのグラフプロファイルエントリの報告を抑制します。このオプションは、指定された実行可能イメージのローカルシンボルを –E の除外リストに指定することと同等です。

–n

フラットプロファイルおよびグラフプロファイルのリストのサイズを、上位 n の問題のある関数に制限します。

–s

指定されたすべてのプロファイルファイルのプロファイル情報の合計を示すプロファイルファイル gmon.sum を生成します。このサマリープロファイルファイルは、a.out ファイルの複数の実行のプロファイルデータを累積するために、gprof (–s を指定) の後続の実行に渡すことができます。–D オプションも参照してください。

–V
–-version

バージョン情報を出力してすぐに終了します。

–z

使用されていないルーチン (呼び出し回数および累積された時間で示されます) を表示します。これは、–c オプションと組み合わせると、呼び出されたことがないルーチンを検出するために役に立ちます。共有オブジェクトのテキスト空間は –c オプションによって検査されないため、動的にリンクされた実行可能ファイルの場合は使用が制限されます。

–?
–-help

使用法に関するメッセージを出力したあと、すぐに終了します。

環境変数

PROFDIR

この環境変数に値が含まれている場合、そのディレクトリ内の pid.programname という名前のファイルにプロファイリング出力が書き込まれます。pid はプロセス ID であり、programname はプログラムが呼び出されたときの argv[0] からパス接頭辞を削除することによって判別されるプロファイルされるプログラムの名前です。変数に NULL 値が含まれている場合、プロファイリングの出力は生成されません。それ以外の場合、プロファイリング出力は gmon.out ファイルに書き込まれます。

ファイル

a.out

名前リストが含まれている実行可能ファイル

gmon.out

動的なコールグラフおよびプロファイル

gmon.sum

集約された動的なコールグラフおよびプロファイル

$PROFDIR/pid.programname

属性

属性についての詳細は、マニュアルページの attributes(7) を参照してください。

属性タイプ
属性値
使用条件
developer/base-developer-utilities

関連項目

cc(1), ld.so.1(1), prof(1), exit(2), pcsample(2), profil(2), malloc(3C), monitor(3C), malloc(3MALLOC), attributes(7), prof(7)

Graham, S.L.、Kessler, P.B.、McKusick, M.K. 著、『gprof: A Call Graph Execution Profiler Proceedings of the SIGPLAN '82 Symposium on Compiler Construction』、SIGPLAN Notices、Vol. 17、No. 6、120-126 ページ、1982 年 6 月。

OracleSolaris 11.4 リンカーとライブラリガイド

実行可能イメージが取り除かれ、.symtab シンボルテーブルがない場合、gprof はグローバル動的シンボルテーブル .dynsym および .SUNW_ldynsym (存在する場合) を読み込みます。動的シンボルテーブル内のシンボルは、.symtab にあるシンボルのサブセットです。.dynsym シンボルテーブルには、ランタイムリンカーによって使用されるグローバルシンボルが含まれています。.SUNW_ldynsym.dynsym の情報をローカル関数のシンボルで拡張します。.dynsym が見つかって .SUNW_ldynsym が見つからない場合は、グローバルシンボルの情報のみを使用できます。ローカルシンボルがない場合、動作は –a オプションの説明と同じです。

プロファイリングするプログラムをコンパイルするときに、LD_LIBRARY_PATH に /usr/lib をコンポーネントとして含めないでください。LD_LIBRARY_PATH に /usr/lib が含まれている場合、プログラムは /usr/lib/libp のプロファイリングバージョンのシステムライブラリと正しくリンクされません。

同一の実行を連続して行なったときに報告される時間が異なる場合があります。これは、ほかのプロセスとキャッシュを共有したことによってキャッシュヒット率が変化したためです。マシンを使用しているプログラムが 1 つのみのように見えていても、隠れているバックグラウンドプロセスまたは非同期プロセスがデータに影響することがあります。まれに、プログラムの記録を開始するクロックティックがプログラムのループに影響して測定が大幅に歪むことがあります。ただし、呼び出し回数は常に正確に記録されます。

monitor への最後の呼び出しが明示的にコーディングされていない場合、プロファイルファイルの生成が保証されるのは、exit を呼び出すプログラムまたは main から戻るプログラムのみです。

mcount()_mcount()moncontrol()_moncontrol()monitor()_monitor() などの関数が gprof の報告に表示されることがあります。これらの関数はプロファイリングの実装の一部であり、実行時のオーバーヘッドが多少あります。これらの関数はプロファイルされていないアプリケーションにはないため、アプリケーションのパフォーマンスを評価する場合、これらの関数の累積時間および呼び出し回数は無視できます。

64 ビットプロファイリング

64 ビットのプロファイリングは、動的にリンクされた実行可能ファイルで自由に使用できます。オブジェクトがプロファイリング用にコンパイルされている場合は、共有オブジェクトのプロファイリング情報が収集されます。ほかの共有オブジェクトのシンボルが同じ名前である可能性があるため、プロファイルの出力を解釈するときに注意する必要があります。プロファイルの出力で名前の重複が発生した場合は、シンボルインデックスリストのシンボル名の前にあるモジュール ID 接頭辞を使用すると、シンボルの該当するモジュールを識別できます。

–s または –D オプションを使用して複数のプロファイルファイルを集約する場合は、32 ビットのプロファイルファイルと 64 ビットのプロファイルファイルを混同しないように注意する必要があります。

32 ビットプロファイリング

32 ビットプロファイリングは動的にリンクされた実行可能ファイルに使用できますが、注意する必要があります。32 ビットプロファイリングでは、共有オブジェクトは gprof でプロファイルできません。このため、プロファイルされた動的にリンクされたプログラムを実行すると、イメージの main の部分のみが標本収集されます。これは、main オブジェクトの外部で費やされたすべての時間 (つまり、共有オブジェクトで費やされた時間) は、プロファイルサマリーに含められないことを意味し、プログラムで報告される合計時間が、プログラムによって使用された合計時間より少ない場合があります。

共有オブジェクトに費やされる時間は計測できないため、プログラムを gprof でプロファイルする場合は、共有オブジェクトの使用は最小限にしてください。必要な場合は、プログラムを共有オブジェクトではなくプロファイルされたバージョンのライブラリ (またはプロファイリングバージョンがない場合は、標準のアーカイブバージョン) にリンクして、ライブラリの関数のプロファイル情報を取得してください。プロファイルされたライブラリのバージョンは、システムの /usr/lib/libp ディレクトリに配置されている場合があります。プロファイリングについては、コンパイラドライバのドキュメントを参照してください。

極端な場合を考えてみます。共有 C ライブラリと動的にリンクされたプロファイルされたプログラムが、いくつかの libc ルーチン (malloc() など) で 100 単位時間を費やします。malloc() はルーチン B からのみ呼び出され、B は 1 単位時間のみを消費するとします。さらに、ルーチン A は、イメージの main (プロファイルされている) 部分のほかのどのルーチンよりも多い 10 単位時間を消費するとします。この場合、gprof は、ほとんどの時間は A で費やされ、B ではほとんど時間が費やされなかったと判断します。このことから、ルーチン A ではなくルーチン B を調査することによって大きな改善を望むのは、ほとんど不可能です。この場合のプロファイラの値は非常に劣化しています。これを解決するには、プロファイリングにアーカイブをできるかぎり使用します。

バグ

プロファイルされていない親には、プロファイルされた子の時間が伝播されますが、それらはコールグラフリストで自然発生的に呼び出されたように見え、時間はそれ以上伝播されません。同様に、シグナルキャッチャーは、プロファイルされていても自然発生的に見えます (原因はさらに不明です)。シグナルキャッチャーがプロファイリングルーチンの実行中に呼び出された場合 (この場合はすべてが失われます) を除き、シグナルキャッチャーのプロファイルされた子の時間は適切に伝播されるべきです。