如何获得调用父母的libc6符号(例如_int_malloc)与Linux perf?

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

例如:

  • _int_malloc占用8%的时间,但没有呼叫父母。
  • __strcmp_sse42__cxxabiv1::__si_class_type_info::__do_dyncast一起占用大约10%的时间,并且具有名称为0呼叫者,其具有不具有呼叫者的呼叫者2d6935c2cc748c6

结果,我无法find哪些例程负责所有这些使用perf的mallocing和dynamic casting。 但是,似乎其他符号(例如malloc但不是_int_malloc )确实有呼叫父母。

为什么不显示呼叫父母_int_malloc? 为什么我找不到__do_dyn_cast的最终来电者? 而且,有什么方法可以修改我的设置,以便我可以获取这些信息? 我在x86-64,所以我想知道如果我需要一个(非标准)libc6框架指针。

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

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

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

但是,开发人员正在努力让perf工具使用DWARF展开信息。 这意味着帧指针不再需要在x86_64上获取回溯信息。 但是,Linus并不想在内核中使用DWARF解卷器。 因此,perf工具将在系统运行时保存寄存器,并使用libunwind库在用户空间perf工具中执行DWARF展开。

此技术已经过测试,可以成功确定(例如) mallocdynamic_cast调用者。 但是,补丁集还没有被集成到Linux内核中,在准备就绪之前需要进一步修改。

_int_malloc__do_dyn_cast被从例程中调用,因为它没有符号表信息。

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

在创建原始unix概要文件之后,还有一个原因。 真正的软件包含几乎所有的时间都用于调用其他函数的函数,而且您需要能够在大部分时间内找到堆栈中的代码,而不是程序大部分时间都是这样。

因此,您需要配置perf以采集堆栈样本,并告诉您每个例程在堆栈上的时间百分比。 如果它报告的不仅仅是例程,而且还包括代码行,就像在缩放中一样 。 最好是在挂钟时间拿样本,所以你不会对IO失明。

所有这一切还有更多要说的。