【问题标题】:Is there any profiler that works with -fomit-frame-pointer on x86_64?是否有任何分析器可以在 x86_64 上与 -fomit-frame-pointer 一起使用?
【发布时间】:2012-03-01 17:31:28
【问题描述】:

没有它,SysProf 无法正确生成调用堆栈,GProf 根本不准确。此外,不使用 -fno-omit-frame-pointer 的分析器是否与依赖它的分析器一样准确?

【问题讨论】:

  • 请记住,联机帮助页本身会警告 -fomit-frame-pointer:“[...] 它还使得在某些机器上无法进行调试。”
  • 我的发行版(Fedora)默认使用它编译。
  • On x86_64 fomit-frame-pointer 是默认值,即使没有在命令行中指定。那是因为有 libunwind,这使得 -fno-omit-frame-pointer 过时了。
  • 如果你想做的是想办法加速程序,首先要明白gprof will disappoint you,其次,测量的精度不是你所需要的。

标签: linux profiling x86-64


【解决方案1】:

可以使用最新版本的linux perf(与--call-graph dwarf):

perf record -F99 --call-graph dwarf myapp

它使用.eh_frames(或.debug_frames)和libunwind 来展开堆栈。

根据我的经验,它有时会丢失。

在 Haswell 上使用最新版本的 perf+kernel,您可以使用 use the Last Branch Record--call-graph lbr

【讨论】:

  • 当我这样做时,perf script 输出中缺少堆栈跟踪。有什么想法吗?
  • @TavianBarnes,我目前拥有相同的issue on Debian,带有 perf_4.0 和 perf_4.1。当切换到 perf_3.16(perf script => perf_3.16 script)时,它按预期工作。我没有(还)检查这是否是上游问题 Debian 软件包的问题。
  • 对于参考,AFAIK 会为每个样本复制磁盘上堆栈的一部分,然后使用 CFI 展开。
  • (CFI 代表“呼叫帧信息”)
【解决方案2】:

我不知道。使用帧指针,遍历堆栈是一个相当简单的练习。您只需取消引用帧指针即可找到旧的帧指针、堆栈指针和指令指针,然后重复直到完成。如果没有帧指针,您将无法在没有附加信息的情况下可靠地遍历堆栈,这在 ELF 平台上通常意味着 DWARF CFI。 DWARF 解析起来相当复杂,并且需要您读取大量附加信息,这在分析器需要工作的时间限制内很难做到。

实现这一点的一种可行方法是简单地保存每个样本的堆栈内存,然后使用 CFI 使其离线以正确展开。根据堆栈的深度,这可能需要相当多的存储空间,并且复制可能会令人望而却步。我从未听说过使用这种技术的分析器,但 Julian Seward floated it as a potential implementation strategy 用于 Firefox 的内置分析器。

【讨论】:

  • 我一直在使用 perf with dwarf (stack unwind) 方法。它无需使用 -fno-omit-frame-pointer 编译即可工作
【解决方案3】:

当 -fomit-frame-pointer 被断言时,大多数分析器将很难工作。如果您想进行合理的分析,您可能不需要使用它并链接到库的调试版本(几乎可以肯定是在没有 -fomit-frame-pointer 的情况下编译的)。

【讨论】:

  • 即使一个库是在没有'-fomit-frame-pointer`的情况下编译的,只要使用了-O选项,它就会被启用:它是x86_64中的默认选项。使用 libunwind,您可以在没有帧指针的情况下进行调试。
猜你喜欢
  • 1970-01-01
  • 2013-01-17
  • 2018-11-10
  • 2014-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-20
  • 1970-01-01
相关资源
最近更新 更多