是否有任何分析器可以在 x86_64 上与 -fomit-frame-pointer 一起使用?

Posted

技术标签:

【中文标题】是否有任何分析器可以在 x86_64 上与 -fomit-frame-pointer 一起使用?【英文标题】:Is there any profiler that works with -fomit-frame-pointer on x86_64? 【发布时间】: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 过时了。 你试过 CodeAnalyst 吗? developer.amd.com/tools/CodeAnalyst/codeanalystlinux/Pages/… 如果你想做的是想办法加速程序,首先要明白gprof will disappoint you,其次,测量的精度不是你所需要的。 【参考方案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,您可以在没有帧指针的情况下进行调试。

以上是关于是否有任何分析器可以在 x86_64 上与 -fomit-frame-pointer 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

intel手册中的x86_64 Opcode编码格式

Android Studio不会将x86_64显示为任何虚拟设备的选项

在 x86/x86_64 处理器上使用 LFENCE 指令是不是有意义?

ARM64 固有的 x86_64 点向量积

是否可以在命令 objcopy 的帮助下进行硬编码

在 x86-64 上,32 位应用程序是不是比 64 位应用程序有性能优势?