Maison  >  Article  >  Tutoriel système  >  Le père de Linux a finalement été convaincu : le langage C du noyau Linux, vieux de 30 ans, sera mis à niveau vers C11

Le père de Linux a finalement été convaincu : le langage C du noyau Linux, vieux de 30 ans, sera mis à niveau vers C11

WBOY
WBOYavant
2024-02-14 21:36:03373parcourir

Il y a eu des nouvelles récemment. Il est passionnant que la version 1989 du noyau Linux en langage C qui a été utilisée ait enfin reçu une mise à niveau majeure. Le rythme de la technologie contemporaine est imparable. Aujourd'hui, la communauté open source Linux a annoncé un plan ambitieux visant à mettre à niveau la version en langage C du noyau vers la norme C11. On s'attend à ce que cette réforme majeure entre en vigueur après la version Linux 5.18, soit en mai prochain. Cette évolution importante apportera des opportunités potentielles illimitées au noyau Linux et l'aidera à mieux s'adapter aux besoins des technologies modernes.

Cette décision a été soudaine. Il n'a fallu qu'une semaine entre le lancement de la question et la déclaration officielle. Il n'est pas facile de convaincre Linus Torvalds, le père obstiné de Linux. La raison semble être un peu accidentelle. Linux 之父终于被劝动:用了 30 年的 Linux 内核 C 语言将升级至 C11

La réaction en chaîne d'un bug

Le problème provient d'une discussion de la communauté Linux la semaine dernière.

Un doctorant nommé Jakob Koschel a découvert un tel problème lors de recherches sur la prévention des vulnérabilités d'exécution spéculative liées aux primitives de liste chaînée du noyau.

Le noyau Linux utilise largement les listes doublement chaînées définies par la structure list_head

 :

struct list_head {
    struct list_head *next, *prev;
    };
Cette structure est souvent intégrée à d'autres structures. De cette manière, des listes chaînées peuvent être créées en utilisant n’importe quel type de structure pertinent.

De plus, le noyau fournit également un grand nombre de fonctions et de macros qui peuvent être utilisées pour parcourir et exploiter des listes chaînées. list_for_each_entry() en fait partie, une macro déguisée en structure de contrôle. Le problème réside dans cette macro. Supposons que le noyau contient la structure suivante :

struct foo {
        int fooness;
    struct list_head list;
    };
Les éléments de

list peuvent être utilisés pour créer une liste doublement chaînée de la structure foo. Supposons qu'il existe une structure appelée foo_list déclarée comme tête d'une telle liste chaînée. Cette liste chaînée peut être parcourue en utilisant le code suivant :

struct foo *iterator;

    list_for_each_entry(iterator, &foo_list, list) {
        do_something_with(iterator);
    }
    /* Should not use iterator here */

L'argument list indique à la macro le nom de la structure list_head dans la structure foo. Cette boucle sera exécutée une fois pour chaque élément de la liste, l'itérateur pointant vers cet élément. Cela entraînait un bug dans le sous-système USB : l'itérateur passé à la macro pouvait toujours être utilisé après avoir quitté la macro.

C'est une chose dangereuse, alors Koschel a soumis un correctif qui corrige le bug en arrêtant d'utiliser l'itérateur après la boucle.

Linux 之父终于被劝动:用了 30 年的 Linux 内核 C 语言将升级至 C11Convaincre Linus

Mais Linus Torvalds lui-même n'aime pas beaucoup ce patch et ne voit pas sa relation avec la vulnérabilité d'exécution spéculative. Après que Koschel l'ait expliqué en détail, Linus a admis qu'il ne s'agissait que d'un bug courant.

Cependant, les choses n'étaient pas si simples, et Linus a vite compris la véritable cause profonde : l'itérateur passé à la macro de parcours de liste chaînée doit être déclaré dans une portée en dehors de la boucle elle-même. Ce bug non prédictif se produit car il n'y a pas de "déclaration de variables dans des boucles" dans C89.

Les macros comme list_for_each_entry () fuient essentiellement toujours la dernière entrée HEAD en dehors de la boucle, simplement parce que nous ne pouvons pas déclarer de variables d'itérateur dans la boucle elle-même.

Si vous pouviez écrire une macro de parcours de liste d'itérateurs qui pourrait se déclarer, alors l'itérateur ne serait pas visible en dehors de la boucle et aucun problème de ce type ne surviendrait. Cependant, le noyau étant bloqué sur le standard C89, les variables ne peuvent pas être déclarées à l'intérieur d'une boucle.

Linus a décidé, passons à la mise à niveau, il est peut-être temps de passer à la norme C99. Bien qu'il ait également plus de 20 ans, il est au moins plus récent que C89 et vous permet de déclarer des variables dans une boucle.

Puisque le C89 est si vieux, pourquoi n’a-t-il pas changé après tant d’années ? Linus a dit que c'était parce que nous avions rencontré des problèmes étranges dans certaines anciennes versions du compilateur gcc et que nous ne pouvions pas les mettre à niveau avec désinvolture.

Cependant, le noyau Linux a désormais augmenté la configuration minimale requise pour gcc à la version 5.1, donc ces bugs étranges du passé devraient disparaître. Linux 之父终于被劝动:用了 30 年的 Linux 内核 C 语言将升级至 C11

Arnd Bergmann, un autre développeur principal, estime que nous pouvons certainement passer à C11 ou même supérieur. Cependant, la mise à niveau vers C17 ou C2x interrompra la prise en charge de gcc-5/6/7, la mise à niveau vers C11 est donc plus facile à réaliser.

En fin de compte, Torvalds était d'accord avec l'idée : "D'accord, rappelez-moi, essayons-le au début de la fenêtre de fusion 5.18." Le passage à C11 pourrait entraîner des bugs inattendus, mais si tout se passe bien, le prochain Linux. la version du noyau passera officiellement à C11.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer