我如何使用 linux perf 获得 libc6 符号(例如 _int_malloc)的呼叫父母

How do I get call parents for libc6 symbols (e.g. _int_malloc) with linux perf?

本文关键字:malloc int 父母 呼叫 例如 linux 何使用 perf 获得 符号 libc6      更新时间:2023-10-16

我正在使用 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 负责所有这些错位和动态转换。 但是,似乎其他符号(例如 malloc但不是_int_malloc)确实有打电话给父母。

为什么表演节目不打电话给父母_int_malloc? 为什么我找不到__do_dyn_cast的最终来电者?而且,我有没有办法修改我的设置,以便我可以获取此信息?我在 x86-64 上,所以我想知道我是否需要一个带有帧指针的(非标准)libc6。

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

使用-gdwarf,就不需要用-fno-omit-frame-pointer编译了。

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

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

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

_int_malloc__do_dyn_cast是从探查器无法识别的例程中调用的,因为它没有它们的符号表信息。

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

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

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

关于这一切,还有更多要说的。