简化现代 GCC 的函数跟踪
Steven Rostedt 想要做一些清理工作,特别是针对内核调试中使用的函数跟踪代码。在那之前,内核可以使用 GCC 的 -pg
标志或 -pg
和 -mfentry
的组合来启用函数跟踪。在每种情况下,GCC 都会创建一个特殊的例程,该例程将在每个函数开始时执行,以便内核可以跟踪对所有函数的调用。仅使用 -pg
,GCC 将在所有 C 函数中创建一个对 mcount()
的调用,而当 -pg
与 -mfentry
结合使用时,它将创建一个对 fentry()
的调用。
Steven 指出,使用 -mfentry
通常被认为是更优越的,以至于内核构建系统总是会选择它而不是 mcount()
替代方案,方法是在编译时测试 GCC,以查看它是否实际支持该命令行参数。
这一切都很正常。由于任何用户可能在其工具链中拥有任何版本的给定软件,或者拥有各种不同的 CPU 等等,每个 CPU 具有不同的功能,因此内核构建系统会运行许多测试,以识别内核将能够依赖的最佳可用功能。
但在这种情况下,Steven 注意到,对于 Linux 版本 4.19,Linus Torvalds 已同意将最低支持的 GCC 版本提升至 4.6。巧合的是,正如 Steven 现在指出的那样,GCC 版本 4.6 是第一个支持 -mfentry
参数的版本。而这正是他的重点——所有受支持的 GCC 版本现在都支持更好的函数跟踪选项,因此内核构建系统根本没有必要坚持 mcount()
的实现。
Steven 发布了一个补丁,将其彻底移除。
Peter Zijlstra 表示支持该计划,Jiri Kosina 也表示支持。特别是 Jiri 对 mcount()
解决方案嗤之以鼻。
Linus 也喜欢 Steven 的补丁,他指出,随着 mcount() 的退出,内核中还有几个区域的存在仅仅是为了帮助在 mcount()
和 fentry()
之间进行选择,而现在这些区域也可以被删除。但 Steven 回复说,虽然是的,这应该完成,但他仍然希望将其拆分为单独的补丁,以保持整洁。
事实证明,Steven 的补丁实际上仅适用于 x86 内核端口。正如 Josh Poimboeuf 指出的那样,许多其他架构仍然使用 mcount()
。Steven 证实,“当您有一个将返回地址压入堆栈然后跳转到另一个位置的单指令时,fentry 工作得很好。使用链接寄存器实现起来要棘手得多。其他架构有一些不同的实现,但 mcount 恰好是大多数架构支持的实现。”
事情就是这样。Steven 的补丁肯定会在完全准备就绪后进入内核。在相对较大的决定(更改最低支持的 GCC 版本)之后,观看这些细节逐渐清晰令人愉快。我想象内核中还有几个区域可以简化和清理,因为它们不必再支持旧版本的 GCC。
注意:如果您在上面被提及并且想在评论区上方发布回复,请将包含您的回复文本的消息发送至 ljeditor@linuxjournal.com。