简化现代 GCC 的函数跟踪

作者:Zack Brown

Steven Rostedt 想要做一些清理工作,特别是针对内核调试中使用的函数跟踪代码。在那之前,内核可以使用 GCC-pg 标志或 -pg-mfentry 的组合来启用函数跟踪。在每种情况下,GCC 都会创建一个特殊的例程,该例程将在每个函数开始时执行,以便内核可以跟踪对所有函数的调用。仅使用 -pg,GCC 将在所有 C 函数中创建一个对 mcount() 的调用,而当 -pg-mfentry 结合使用时,它将创建一个对 fentry() 的调用。

Steven 指出,使用 -mfentry 通常被认为是更优越的,以至于内核构建系统总是会选择它而不是 mcount() 替代方案,方法是在编译时测试 GCC,以查看它是否实际支持该命令行参数。

这一切都很正常。由于任何用户可能在其工具链中拥有任何版本的给定软件,或者拥有各种不同的 CPU 等等,每个 CPU 具有不同的功能,因此内核构建系统会运行许多测试,以识别内核将能够依赖的最佳可用功能。

但在这种情况下,Steven 注意到,对于 Linux 版本 4.19Linus 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。

Zack Brown 是 Linux JournalLinux Magazine 的技术记者,并且曾是 “Kernel Traffic” 每周新闻通讯和 “Learn Plover” 速记打字教程的作者。他于 1993 年在他的 386 电脑上安装了 Slackware Linux,配备了 8MB 内存,并被开源社区彻底震撼。他是 Crumble 纯策略棋盘游戏的创始人,您可以使用一些纸板自行制作。他还喜欢写小说、尝试动画、改革拉班舞谱、设计和缝制自己的衣服、学习法语以及与朋友和家人共度时光。

加载 Disqus 评论