如何使用linux perf获取libc6符号(例如_int_malloc)的调用父项?

时间:2012-04-18 16:00:57

标签: c++ linux g++ profiling perf

我正在使用linux perf分析C ++应用程序,我使用GProf2dot获得了一个很好的控制流图。但是,来自C库(libc6-2.13.so)的一些符号占用了总时间的很大一部分,但没有内边缘。

例如:

  • _int_malloc占用了8%的时间,但没有致电父母。
  • __strcmp_sse42__cxxabiv1::__si_class_type_info::__do_dyncast一起占用大约10%的时间,并且有一个名为0的来电者,其来电者为2d6935c2cc748c ,和6,没有来电者。

结果,我无法找出哪些例程负责所有这些mallocing和动态转换只使用perf。但是,似乎其他符号(例如malloc但不是_int_malloc)确实有呼叫父母。

为什么没有为_int_malloc显示呼叫父母?为什么我找不到__do_dyn_cast的最终来电者?并且,有什么方法可以修改我的设置,以便我可以获取此信息吗?我在x86-64上,所以我想知道我是否需要带有帧指针的(非标准)libc6。

2 个答案:

答案 0 :(得分:5)

更新:从3.7.0内核开始,可以使用perf record -gdwarf <command>确定系统库中符号的调用父项。

使用-gdwarf,无需使用-fno-omit-frame-pointer进行编译。

原始回答: 是的,可能需要在x86_64上使用帧指针(-fno-omit-framepointer)编译的libc6,目前(2012年5月24日)。

但是,开发人员目前正在努力允许perf工具使用DWARF展开信息。这意味着不再需要帧指针来获取x86_64上的回溯信息。但是,Linus不希望在内核中使用DWARF开卷器。因此,perf工具将在系统运行时保存寄存器,并使用libunwind库在userspace perf工具中执行DWARF展开。

此技术已经过测试,可成功确定(例如)mallocdynamic_cast的来电者。但是,补丁集尚未集成到Linux内核中,需要在准备好之前进行进一步的修订。

答案 1 :(得分:1)

_int_malloc__do_dyn_cast正在从分析器无法识别的例程中调用,因为它没有符号表信息。

更重要的是,您似乎正在展示自我(独家)时间。 这对于找到a)有很多自我时间的例程中的热点非常有用,并且b)你可以修复。

创建原始unix profil之后的分析器是有原因的。真正的软件包含几乎所有时间都在调用其他函数的函数,并且你需要能够在很多时候找到堆栈中的代码,而不是大部分时间都有程序计数器。

因此,您需要配置perf以获取堆栈样本,并告诉您每个例程在堆栈中的时间百分比。 如果报告不只是例程,而且报告代码行,就像在Zoom中一样。 最好在挂钟时间上采集样本,这样你就不会对IO视而不见了。

There's more to say on all this.