私はLinux環境に取り組んでいます。 2つの「C」ソースパッケージtrainとtest_trainがあります。
ここで、gprofを使用して、メインプログラムとlibtrain.so内の関数の呼び出しシーケンスを示すコールグラフを生成したいと思います。
-pgオプションを使用して両方のパッケージをコンパイルおよびリンクしています。デバッグレベルはo0です。 ./train-testを実行すると、gmon.outが生成されます。それから私はします:
$ gprof -q ./train-test gmon.out
ここで、出力はtrain-testの関数のコールグラフを示していますが、libtrain.soにはありません。
何が問題なのですか?
gprof
は機能しません。代わりにsprof
を使用する必要があります。私はこれらのリンクが役に立ちました:
2番目のリンクからの要約:
手順2で、既存のディレクトリである必要があることがわかりました。そうしないと、役立つ警告が表示されます。また、手順3では、ライブラリをlibmylib.so.X
として指定する必要がある場合があります(おそらく.X.Y
でさえ、わかりません)。それ以外の場合は、警告はまったく表示されません。
ライブラリをPythonから読み込んでいますが、sprof
がうまくいきませんでした。代わりに、Fedoraリポジトリにあるoprofile
を使用しました。少なくとも:
operf --callgraph /path/to/mybinary
アプリケーションが終了するのを待つか、Ctl-cを実行してプロファイリングを停止します。次に、プロファイルの概要を生成しましょう。
opreport --callgraph --symbols
それを解釈するには、 ドキュメント を参照してください。それは一種の混乱です。生成されたレポートでは、各シンボルは独自のブロックにリストされています。ブロックのメインシンボルは、インデントされていないシンボルです。その上の項目はその関数を呼び出す関数であり、その下の項目はそれによって呼び出されるものです。以下のセクションのパーセンテージは、それらの呼び出し先で費やされた相対的な時間です。
Linuxを使用していない場合(Solarisの場合のように)、そこにはsprof
がないため、運が悪いだけです。ライブラリのソースがある場合は、静的ライブラリをリンクし、代わりにそのライブラリを使用してプロファイリングバイナリを作成することで問題を解決できます。共有ライブラリへの呼び出しを追跡するもう1つの方法は、truss
を使用することです。オプション-u [!]lib,...:[:][!]func, ...
実行の呼び出し履歴の良い画像を取得できます。これはプロファイリングと完全に同じではありませんが、シナリオによっては非常に役立つ場合があります。