关于apache:Linux内核C语言将升级

5次阅读

共计 1399 个字符,预计需要花费 4 分钟才能阅读完成。

依据 Linux 内核邮件列表的音讯,社区近日探讨了是否要为内核采纳古代 C 语言规范。
尽管 Linux 内核在疾速倒退,但它同时依赖着一些十分古老的工具,其中之一就是内核代码仍在应用 1989 年版本的 C 语言规范——此规范在 30 多年前内核我的项目启动之前就曾经编写实现。从探讨后果来看,这一状况无望在 5.18 版本内核中扭转。

Jakob Koschel 在向 Linus Torvalds 递交的补丁(https://lkml.org/lkml/2022/2/…)中修复了内核链表相干的预测执行破绽。

Linux 内核 C 语言将降级 Linux 内核 C 语言将降级

起因是 Jakob 发现了一个问题,Linux 内核宽泛应用由 struct list_head 定义的双向链表:

structlist_head{structlist_headnext,prev;};
这种构造体通常被嵌入到其余构造体中,通过这种形式,开发者能够应用任何感兴趣的构造类型制作链表。除此之外,内核还提供了大量可用于遍历和操作链表的函数和宏。其中之一是 list_for_each_entry(),这是一个伪装成控制结构的宏。要理解如何应用此宏,请假如内核蕴含如下构造:

structfoo{intfooness;structlist_headlist;};
list 成员可用于创立 foo 构造体的双向链表,假如咱们有一个叫做 foo_list 的构造申明作为此类链表的头,应用以下代码能够遍历此列表:

struct foo *iterator;
list_for_each_entry(iterator,&foo_list,list){
do_something_with(iterator);
}
/ Should not use iterator here /
list 参数通知宏在 foo 构造中 list_head 构造体的名称。此循环将为列表中的每个元素执行一次,迭代器指向该元素。由此导致了 USB 子系统中的一个 bug: 传递给该宏的迭代器在退出宏后还能被应用。

Koschel 通过从新编写有问题的代码,以在循环后停止使用迭代器来解决问题。

不过 Linus 却对补丁修复的问题示意不解,也没有看到它与预测执行破绽的关系。Koschel 对此进行了进一步解释,对此 Linus 认为这只是一个一般的 bug。但不久之后 Linus 发现了问题的本源所在: 传递给列表遍历宏的迭代器,必须在循环自身之外的范畴内申明。

随后,Linus 认为兴许能够采纳更间接的修复如块级变量申明。但 C89 不反对,而 1999 年公布的 C99 规范反对。所以 Linux 内核兴许是时候转向应用 C99 规范了。

Linus 说到,内核代码始终停留在 C89 的起因之一是编译器 gcc 的旧版本会呈现奇怪的问题,导致初始化程序被毁坏。不过当初内核要求的 GCC 最低版本曾经进步到了 v5.1,那些 bug 可能不再相干了。

另一位亲密关注架构编译器问题的内核开发者 Arnd Bergmann 提议间接降级到 C11 甚至 C2x,只管他不确定 C11 是否会带来任何对内核有用的新内容。不过如果降级到 C17 或 C2x,会毁坏对 gcc-5/6/ 7 的反对,因而降级到 C11 更容易实现,而且逾越太大内核社区未必承受。

Linus 赞成了这个想法,在 Bergmann 确认应该能够这样做之后,Linus 发表将在下一个内核版本 v5.18 中尝试应用 C11 规范。如果一切顺利,下一个内核版本应用的 C 语言规范无望降级到 C11。

正文完
 0