10

gperftools 文档libprofiler应该链接到目标程序:

$ gcc myprogram.c -lprofiler

(不改变程序的代码)。

然后程序应该使用特定的环境变量运行:

CPUPROFILE=/tmp/profiler_output ./a.out

问题是:如何libprofile有机会启动和完成一个分析器,当它只是被加载,但它的函数没有被调用?

该库中没有构造函数(proof)。 库代码中“CPUPROFILE”的所有场合均不涉及启动分析器的任何地方。

我没有想法,下一步该去哪里看?

4

2 回答 2

8

根据链接网页的文档,在链接库下,它描述了 -lprofiler 步骤与使用 LD_PRELOAD 选项链接共享对象文件相同。

共享对象文件与头文件不同。头文件包含编译程序时查找的函数声明,因此函数的名称解析,但名称只是名称,而不是实现。共享对象文件 (.so) 包含函数的实现。有关更多信息,请参阅以下 StackOverflow 答案

/trunk/src/profiler.cc 的源文件在第 182 行,有一个 CPUProfiler 构造函数,它根据 CPUPROFILE 环境变量(第 187 行和第 230 行)检查是否应该启用分析。

然后它在第 237 行调用 Start 函数。根据该文件中的注释,析构函数在第 273 行调用 Stop 函数。

为了回答您的问题,我相信第 132CpuProfiler CpuProfiler::instance_;行是 CpuProfiler 实例化的行。

gperftools 文档中缺乏明确性是已知问题,请参见此处

于 2012-12-01T16:39:24.450 回答
0

我认为探查器使用 profile-handler.cc 底部的 REGISTER_MODULE_INITIALIZER 宏进行初始化(以及 heap-checker.cc、heap-profiler.cc 等)。这会调用 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 回答