Ubuntu 24.04 LTS 将默认启用帧指针

Ubuntu 24.04 LTS 将默认使用帧指针编译二进制文件,逆转了旧时为了在 32 位 x86 上获得额外寄存器而省略帧指针的优化。评论者认为,在现代 64 位 CPU 上,这种性能损失通常远低于 1–2%,而可观测性收益却相当显著:栈回溯更可靠,perf、eBPF/bpftrace 和持续剖析器等工具更容易使用,而且即使没有完整调试符号,也能更好地进行事后调试。一些人担心 Python 解释器这类对性能极其敏感的工作负载会出现回退,但逐渐形成的共识是,发行版应默认优先考虑可调试性,并仅对确实出现明确、可测量降速的工作负载选择性关闭。

背景与动机

  • 许多评论者认为省略帧指针是 32 位 x86 时代的一种遗留微优化;当时回收帧指针能多出一个关键寄存器,并带来显著的速度提升。
  • 在 x86-64 上,可用寄存器更多也更宽,因此省略帧指针带来的收益被认为小得多。
  • 还有几位提到其他发行版(例如 Fedora)已经启用了帧指针,并认为 Ubuntu 的这一举动是更广泛趋势的一部分。

性能影响争论

  • 在 64 位架构上,据称开销通常“很难测量”,往往低于 1%,也有一些说法称在特定工作负载下会有 1–2% 的影响。
  • 反对者认为,哪怕全局出现 0.1–1% 的回退,在大规模场景下也会造成浪费,而且工具本身应该修好,做到无需帧指针也能分析性能。
  • 支持者则反驳说,便捷获取性能剖析数据往往能带来 30–3000% 的优化,因此这种权衡显然更划算。
  • 也有人提到一些微观场景里额外寄存器仍然很重要(例如 Python 这类字节码解释器、紧密的热点循环),并预计或支持按包进行例外关闭。

调试与剖析收益

  • 大多数人一致认为,帧指针能让栈回溯变得简单、低成本且更可靠,尤其适用于:
    • Perf、eBPF/bpftrace/bcc 工具、持续剖析和火焰图。
    • LTS 系统上的事后调试、核心转储和生产事故分析。
  • 没有帧指针时,工具必须依赖 DWARF/.eh_frame 展开程序;它们更慢、更复杂,而且在栈被破坏时更脆弱。

工具、格式与内核支持

  • 讨论中提到,已经有一些不依赖帧指针、通过 DWARF+eBPF 进行栈展开的方案,但它们很复杂,也并非广泛可用或适用于所有工具。
  • 还讨论了内核自身使用的 ORC unwind 机制,以及面向未来用户态栈回溯、开销更低的 SFrame 格式。
  • 有人认为,今天依赖先进的展开格式并不现实;帧指针可以立即与现有工具链配合使用。

特殊情况、安全性与生态影响

  • Python 被举例称在启用帧指针时曾出现约 10% 的回退;Ubuntu 计划在确认后排除这类情况。
  • 嵌入式系统往往会剥离调试/展开信息,因此在那类环境中帧指针尤其有价值。
  • 有一条评论指出,省略帧指针会略微减少某些栈溢出利用面,但这一推理并未进一步展开。
  • 还存在关于这种默认设置应由发行版决定还是交给上游的问题;另一些人则回应说,运维者和用户也需要系统级可观测性。