web-dev-qa-db-ja.com

gprof:メインプログラムにリンクされている共有ライブラリ内の関数のコールグラフを生成する方法

私はLinux環境に取り組んでいます。 2つの「C」ソースパッケージtrainとtest_trainがあります。

  1. コンパイル時にtrainパッケージはlibtrain.soを生成します
  2. test_trainはlibtrain.soにリンクし、実行可能なtrain-testを生成します

ここで、gprofを使用して、メインプログラムとlibtrain.so内の関数の呼び出しシーケンスを示すコールグラフを生成したいと思います。

-pgオプションを使用して両方のパッケージをコンパイルおよびリンクしています。デバッグレベルはo0です。 ./train-testを実行すると、gmon.outが生成されます。それから私はします:

$ gprof -q ./train-test gmon.out

ここで、出力はtrain-testの関数のコールグラフを示していますが、libtrain.soにはありません。

何が問題なのですか?

23
atv

gprofは機能しません。代わりにsprofを使用する必要があります。私はこれらのリンクが役に立ちました:

2番目のリンクからの要約:

  1. 共有ライブラリ(libmylib.so)をデバッグ(-g)モードでコンパイルします。いいえ-pg。
  2. lD_PROFILE_OUTPUT = `pwd`をエクスポートします
  3. lD_PROFILE = libmylib.soをエクスポートします
  4. rm -f $ LD_PROFILE.profile
  5. libmylib.soをロードするプログラムを実行します
  6. sprof PATH-TO-LIB/$ LD_PROFILE $ LD_PROFILE.profile -p> log
  7. ログを参照してください。

手順2で、既存のディレクトリである必要があることがわかりました。そうしないと、役立つ警告が表示されます。また、手順3では、ライブラリをlibmylib.so.Xとして指定する必要がある場合があります(おそらく.X.Yでさえ、わかりません)。それ以外の場合は、警告はまったく表示されません。

20
Dan

ライブラリをPythonから読み込んでいますが、sprofがうまくいきませんでした。代わりに、Fedoraリポジトリにあるoprofileを使用しました。少なくとも:

operf --callgraph /path/to/mybinary

アプリケーションが終了するのを待つか、Ctl-cを実行してプロファイリングを停止します。次に、プロファイルの概要を生成しましょう。

opreport --callgraph --symbols

それを解釈するには、 ドキュメント を参照してください。それは一種の混乱です。生成されたレポートでは、各シンボルは独自のブロックにリストされています。ブロックのメインシンボルは、インデントされていないシンボルです。その上の項目はその関数を呼び出す関数であり、その下の項目はそれによって呼び出されるものです。以下のセクションのパーセンテージは、それらの呼び出し先で費やされた相対的な時間です。

2
Jim Hunziker

Linuxを使用していない場合(Solarisの場合のように)、そこにはsprofがないため、運が悪いだけです。ライブラリのソースがある場合は、静的ライブラリをリンクし、代わりにそのライブラリを使用してプロファイリングバイナリを作成することで問題を解決できます。共有ライブラリへの呼び出しを追跡するもう1つの方法は、trussを使用することです。オプション-u [!]lib,...:[:][!]func, ...実行の呼び出し履歴の良い画像を取得できます。これはプロファイリングと完全に同じではありませんが、シナリオによっては非常に役立つ場合があります。

0