10

gperftools のドキュメントにはlibprofiler、ターゲット プログラムにリンクする必要があると記載されています。

$ gcc myprogram.c -lprofiler

(プログラムのコードを変更することなく)。

次に、特定の環境変数を使用してプログラムを実行する必要があります。

CPUPROFILE=/tmp/profiler_output ./a.out

問題はlibprofile、プロファイラーがロードされただけで、その関数が呼び出されていない場合、どのようにしてプロファイラーを開始および終了する機会があるかということです。

そのライブラリにはコンストラクタ関数はありません (証明)。 ライブラリ コード内の「CPUPROFILE」はすべて、プロファイラーが開始される場所を指すわけではありません。

次はどこを見ればいいですか?

4

2 に答える 2

8

リンクされたWebページのドキュメントによると、ライブラリのリンクの下で、-lprofilerステップは、LD_PRELOADオプションを使用して共有オブジェクトファイルに対してリンクすることと同じであると説明されています。

共有オブジェクト ファイルは、単なるヘッダー ファイルとは異なります。ヘッダー ファイルには、プログラムのコンパイル時に によって参照される関数宣言が含まれているため、関数の名前は解決されますが、名前は単なる名前であり、実装ではありません。共有オブジェクト ファイル (.so) には、関数の実装が含まれています。詳細については、次の StackOverflow answerを参照してください。

行 182の /trunk/src/profiler.cc のソース ファイルには、CPUPROFILE 環境変数に基づいてプロファイリングを有効にするかどうかをチェックする CPUProfiler コンストラクターがあります (行 187 および行 230)。

次に、237 行目で Start 関数を呼び出します。このファイルのコメントに従って、デストラクタは 273 行目で Stop 関数を呼び出します。

あなたの質問に答えるためにCpuProfiler CpuProfiler::instance_;、行 132 は CpuProfiler がインスタンス化される行だと思います。

gperftools のドキュメントのこの不明確さは既知の問題です。こちらを参照してください。

于 2012-12-01T16:39:24.450 に答える
0

プロファイラーは、profile-handler.cc (および heap-checker.cc、heap-profiler.cc など) の下部にある REGISTER_MODULE_INITIALIZER マクロで初期化されると思います。これは、ライブラリが読み込まれたときにコンストラクターが呼び出されるダミーの静的オブジェクトを定義する src/base/googleinit.h を呼び出します。次に、そのダミー コンストラクターが ProfileHandlerRegisterThread() を呼び出し、pthread_once 変数を使用してシングルトン オブジェクト (ProfileHandler::instance_) を初期化します。

関数 REGISTER_MODULE_INITIALIZER は、Linux のロード可能なカーネル モジュールに見られる module_init()/module_exit() 関数をシミュレートします。

(私の答えは、gperftools の 2.0 バージョンに基づいています)

于 2013-08-07T06:29:36.420 に答える