8

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

例如:

  • _int_malloc花费 8% 的时间,但没有给父母打电话。
  • __strcmp_sse42总共__cxxabiv1::__si_class_type_info::__do_dyncast花费大约 10% 的时间,并且有一个名为 的呼叫者0,其中有呼叫者2d6935c2cc748c6,没有呼叫者。

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

为什么 perf show 不为 _int_malloc 调用父母?为什么我找不到 __do_dyn_cast 的最终调用者?而且,有什么方法可以让我修改我的设置,以便我可以获得这些信息吗?我在 x86-64 上,所以我想知道是否需要带有帧指针的(非标准)libc6。

4

2 回答 2

5

更新:从 3.7.0 内核开始,可以使用perf record -gdwarf <command>.

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

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

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

该技术已经过测试,可以成功确定(例如)mallocdynamic_cast. 但是,补丁集还没有集成到 Linux 内核中,需要进一步修改才能准备好。

于 2012-05-24T20:04:14.713 回答
1

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

更重要的是,看起来你正在展示自我(独家)时间。这仅对在 a) 有很多自用时间和 b) 您可以修复的例程中查找热点有用。

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

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

这一切还有很多话要说。

于 2012-04-20T12:58:53.933 回答