【问题标题】:How exactly does gperftools CPU profiler start?gperftools CPU profiler 究竟是如何启动的?
【发布时间】:2012-11-29 06:19:28
【问题描述】:

gperftools documentation 表示libprofiler 应该链接到目标程序:

$ gcc myprogram.c -lprofiler

(不改变程序代码)。

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

CPUPROFILE=/tmp/profiler_output ./a.out

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

该库中没有构造函数 (proof)。 库代码中的All occasions of "CPUPROFILE" 不引用任何启动分析器的地方。

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

【问题讨论】:

    标签: gcc linker dynamic-linking google-perftools gperftools


    【解决方案1】:

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

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

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

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

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

    gperftools 文档中缺乏明确性是已知问题,请参阅here

    【讨论】:

    • 您好 Appleman1234,感谢您的回答。是的,您指出的行号与 CPUPROFILE 环境变量有关。但是他们会检查该环境变量的 absence,而不是存在。这意味着 CpuProfiler 已经在某处实例化,具体取决于分析器的 .so 链接(然后构造函数检查变量是否存在等)。而且还没有这样的地方!库可以在加载时做出反应,但这个没有(我在 OP 帖子中放置了一位教授)。任何想法(以及如何/为什么)仅仅因为链接而自动实例化 CpuProfile?
    • 哦,对了!这正是这个地方。谢谢版主,终于明白了。非常感谢。
    【解决方案2】:

    我认为探查器是使用 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版本)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      • 2021-08-15
      • 2012-06-08
      相关资源
      最近更新 更多