Aller au contenu

Erreurs de calculs : conséquences et conclusions

Vol 501 d'Ariane⚓︎

Nombre de bits insuffisant

Comme toutes les fusées (les avions, les navires, les missiles aussi d'ailleurs...), Ariane 5 est dotée d'une centrale inertielle, instrument qui permet à l'appareil de se repérer dans l'espace et de suivre la trajectoire prévue. Une centrale inertielle est composée pour l'essentiel d'accéléromètres, de gyroscopes et de calculateurs, qui mesurent des accélérations et des angles sur les trois axes de l'espace et qui intègrent ces données mesurées pour calculer des vitesses et des positions. Les accéléromètres et les gyroscopes sont des capteurs qui convertissent des caractéristiques mécaniques (resp. accélération et angle) en grandeurs électriques qui sont alors numérisées, converties en nombres manipulables par un calculateur.

Et nous arrivons au coeur du problème, plus précisément sur l'information délivrée par un accéléromètre sur l'axe horizontal de la centrale. La centrale inertielle utilisée sur Ariane 5 était identique à celle utilisée sur Ariane 4. Après tout, les principes de guidage et les informations de navigation nécessaires sont les mêmes. Et la centrale inertielle d'Ariane 4 fonctionnait parfaitement !

Le premier tir d'Ariane 5 eut lieu le 4 juin 1996. 37 secondes après le décollage, la trajectoire de la fusée est sortie du nominal, la fusée a perdu un booster, ce qui déclencha son auto-destruction. Tout ça à cause d'un dépassement de buffer sur une donnée issue d'un accéléromètre horizontal. Il faut savoir que les accélérations horizontales max. d'Ariane 5 sont 5 fois plus fortes que celles d'Ariane 4 et que sa trajectoire après décollage est différente de celle d'Ariane 4, qui implique des accélérations horizontales importantes.

Sur Ariane 4, la valeur numérique maximale délivrée par le capteur était égale à 64, codée sur un entier court de 8 bits, largement suffisant pour coder un nombre entier égal à 64 au maximum. Le gros hic c'est que la valeur d'accélération délivrée par le capteur d'Ariane 5 lors du décollage est très supérieur, de l'ordre de 300 max. Et comme vous le savez, il n'est pas possible de coder 300 sur 8 bits (on code de 0 à 255). Il aura fallut un entier de 16 bits ou plus. Cela génère un dépassement de buffer et si l'exception n'est pas traitée, le programme se "plante". Ce qui arriva sur la centrale inertielle principale. Le calculateur de la centrale étant redondé, la centrale de secours a pris le relais et se planta immédiatement pour les mêmes raisons, le logiciel étant le même dans les deux cas.

Ce qu'il faut retenir de cet exemple

  • Lorsqu'on travaille sur un système d'acquisition de données, il faut toujours traiter les dépassements de buffer dûs à des valeurs numériques, délivrées de façon normale ou accidentelle, qui seraient hors des bornes autorisées par le type des variables dans lesquelles le système va stocker les données, que ce soit dans vos programmes, les bases de données ou les interfaces.
  • Il faut toujours procéder aux tests de robustesse du système, en injectant des données hors domaine de validité nominale des données pour vérifier le comportement du système. Celui-ci ne doit jamais se planter, mais procéder au traitement adéquat de l'exception et poursuivre son process. Les ingénieurs du CNES n'ont pas effectué les tests en pensant que la centrale d'Ariane 4 fonctionnait et donc que ce n'était pas utile et que cela permettait une économie de 800 000 francs (le coût du crash fut d'environ 500 millions de dollars !).
  • La redondance des calculateurs en normal/secours ne permet pas de pallier les dysfonctionnements logiciels, lorsque les logiciels sur les calculateurs principaux et secours sont identiques. Dans les systèmes hautement critiques, essentiellement militaires et spatiaux, la redondance est assurée par plusieurs calculateurs (3 ou 5), qui travaillent en logique majoritaire (les résultats des calculs sont comparés et la majorité l'emporte, d'où le nombre impair de calculateurs) et les logiciels sur chaque calculateur sont conçus et testés par des équipes différentes.

Panne sur le croiseur USS Yorktown (CG 48) de l'US Navy⚓︎

Problème de division par zéro

Un autre cas d'invalidité des données d'entrée dans un système d'acquisition, moins pénalisant financièrement mais plus inquiétant. Le 21 septembre 1997, l'USS Yorktown CG-48, un croiseur de classe Aegis, fut victime d'une panne de son système de propulsion qui l'immobilisa, heureusement alors qu'il était à l'entraînement au large de la Virginie.

L'USS Yorktown fut le premier navire de l'US Navy à recevoir un système de gestion intégrée des systèmes de navigation, propulsion, communications et supervision des équipements, le système Smart Ship System (SSS) issu du programme SSPO (Smart Ship Program Office). Les systèmes de combats n'étaient pas concernés, mais que fait un croiseur sans propulsion ni communications ? Signalons que le but du programme SSPO était de réduire de 40 à 4 le nombre des personnels chargés de la conduite du navire...

Le SSS était composé de 27 PC tournant sous Windows NT 4.0, reliés entre eux et à un serveur par un LAN sur fibre optique. NT 4.0 n'était pas réputé pour sa fiabilité, sa robustesse et son endurance (il fallait rebooter fréquemment à cause des fuites mémoire du système).

Donc, lors de l'entraînement, un marin constate qu'une vanne est physiquement fermée alors que le superviseur de SSS (Smart Ship's Standard Machinery Control System) indique qu'elle est ouverte. Problème de capteur assez classique en supervision. Notre marin va donc tenter de modifier manuellement, dans la base de données d'états du système, l'état de la vanne en saisissant dans l'IHM du gestionnaire de la base de données la valeur 0 dans un attribut de reset de la vanne. Il se trouve que cet attribut était utilisé dans une division, au diviseur... Bien sûr, le programme a produit une exception de division par zéro. Et le programme ne traitait pas cette exception, le programmeur ayant sans doute pensé que cet attribut ne pouvait pas prendre une valeur nulle. Le programme s'est planté et l'erreur s'est propagée à l'ensemble des programmes du SSS : panne de propulsion. Imaginez la même situation au combat ...

Ce qu'il faut retenir de cet incident

  • Toutes les données introduites manuellement dans un système doivent être testées et validées avant d'être enregistrées, tant dans leur appartenance au domaine de validité fonctionnelle que dans l'adéquation de leur valeur avec le type de variables amenées à les stocker.
  • Toutes les exceptions doivent être traitées : c'est une règle de l'art fondamentale. Nous verrons plus loin comment les normes nous y aident, en particulier l'IEEE-754.
  • Les systèmes d'acquisition et de traitement doivent être robustes, tolérants aux fautes. C'est une affaire de rigueur de conception, et cela doit être testé. Ignorer les tests de robustesse d'un programme est une grave erreur. C'est vrai pour les ingénieurs des systèmes critiques, mais ça l'est aussi pour les physiciens expérimentateurs à qui l'on confie des machines qui peuvent être dangereuses et qui sont souvent hors de prix.
  • Quand on conçoit et développe un système hautement critique (un système de gestion d'un navire de guerre) ou même un système critique (un gestionnaire de réseau électrique ou un accélérateur de particules, par exemple), on ne doit pas sacrifier les efforts de conception et de tests d'un système résilient sur l'autel du planning ou des coûts. L'ingénieur ou le physicien responsable doit savoir résister aux contraintes externes pour livrer un système performant ET résilient.
  • Incidemment, mais ce n'est pas un problème d'arithmétique sur les ordinateurs, il faut choisir l'OS approprié pour construire un système d'acquisition ou de traitement critique. Windows NT 4.0 n'était vraiment pas approprié et le choix d'Unix aurait été préférable (comme c'est le cas aujourd'hui dans l'US Navy). Même si les nouvelles générations de Windows sont plus robustes, je déconseille pour ma part l'usage de cet OS pour construire un système d'acquisition de données ou de calcul intensif.

Echec d'interception d'un SCUD par un Patriot à Dhahran⚓︎

Erreur d'arrondi aux conséquences humaines désastreuses

Le système de missiles anti-missiles Patriot (MIM-104F - PAC3) fut la star de la première guerre du Golfe. Sa mission était d'empêcher les SCUD (un missile balistique de fabrication soviétique) irakiens d'atteindre les troupes coalisées stationnées au Koweït et en Arabie Saoudite.

Le 25 février 1991, un SCUD fut lancé contre la base US Army de Dhahran (Arabie Saoudite). La batterie de Patriot qui assurait sa défense anti-aérienne a bien détecté le missile, l'a engagé et a tiré un missile pour l'intercepter. Ce missile a loupé sa cible de plus de 500 mètres, alors que la précision habituelle du système est d'environ un mètre (en mode ABM, la charge militaire est une charge cinétique : les missiles balistiques vont plus vite que l'onde d'explosion, ce qui rend inopérant les charges explosives déclenchées par proximité en ABM). Le SCUD provoqua la mort de 28 personnes et en blessant plus ou moins gravement 100 autres.

L'enquête montra qu'une erreur d'arithmétique du calculateur, plus précisément des arrondis cumulés, fut à l'origine de la catastrophe.

Pour comprendre ce qu'il s'est passé, il faut retenir deux données essentielles :

  • Le calculateur de tir du Patriot possède une horloge qui génére un temps en dixièmes de secondes. L'horloge est initialisée au démarrage de la batterie, et le temps courant est exprimé en multiples de dixièmes de secondes.
  • Au moment de l'attaque du SCUD, la batterie était en service depuis 100 heures.

  • Dans le calculateur de tir, le temps est stocké en binaire dans un registre de 24 bits. Mais essayez de convertir 1/10 de seconde en binaire : vous allez être obligé d'arrondir le résultat. Oh pas de beaucoup : environ \(9.5\times10^{-8}\) seconde. Cela semble peu, mais comptez combien il y a de pas d'horloge au dixième de seconde dans 100 heures : \(3.6\times10^{6}\). Ce qui représente une erreur d'arrondi du temps de \(9.5\times10^{-8}\times3.6\times10^{6} = 0.34\) seconde. Le temps écoulé est sous-estimé de 0.34 s. Un SCUD en phase balistique vole à \(1~676~m.s^{-1}\). En 0.34 seconde, il parcourt 570 mètres de plus que prévu par le calculateur : l'interception échoue.

Conclusion

Nous sommes en présence d'un cumul d'erreurs dues aux arrondis successifs. Pour l'anedocte si l'on peut dire, les israéliens, eux aussi utilisateurs de Patriot, ont prévenus les américains du problème le 11 février 1991. Le patch de correction a été transmis le 26 février 1991. La seule parade qu'avait indiqué le constructeur du Patriot, Raytheon, était de rebooter le calculateur régulièrement, mais il semble que les servants n'aient pas compris pourquoi ...

Dans ce cas, il s'agit clairement un défaut de conception, aggravé par une absence de test d'endurance :

  • Le pas d'horloge aurait du être choisi pour être représentable en binaire sans arrondi. L'effet du cumul de l'arrondi a sans doute été négligé ou pire ignoré. Il existe pourtant des algorithmes pour traiter les cumuls d'arrondis !
  • Un test d'endurance du logiciel aurait sans aucun doute permis de détecter la dérive de précision dans la valeur du temps lue dans le registre. Certes, ce genre de test est assez compliqué et long, mais son absence se paye très cher : ici 28 vies.

Autres erreurs du même genre⚓︎

Erreurs de troncature, d'ALU, d’affichage et d'unités

L'histoire de l'informatique est riche d'erreurs plus ou moins dramatiques du même genre, par exemple :

  • En 1982, la bourse de Vancouver créa un nouvel indice boursier de valeur initiale égale à 1000. Cet indice était recalculé après chaque transaction. Plutôt que d'arrondir le résultat, le programmeur l'a tronqué à la troisième décimale. Mal lui en a pris, après 22 mois de fonctionnement, la valeur calculée de l'indice était de 524.881 alors qu'elle aurait du être de 1098.811 : imaginez la tête des investisseurs ! Les erreurs de troncature sont pernicieuses : elles sont toujours de même signe et ne se compensent donc jamais.
  • En 1994, Intel sort son processeur Pentium 60 (P4) et 66 (P5) en grande pompe. Après quelques jours, le professeur Nicely signale un bug, le bug FDIV : les résultats de division en virgule flottante sont parfois faux ! Un problème de gravure de table de constantes utilisées dans l'algorithme de division de l'ALU (Arithmetic-Logic Unit) du processeur !
  • Si vous avez encore le tableur Excel 2007 à disposition, calculez 850 x 77.1 : au lieu de 65535 vous verrez s'afficher 100 000 !
  • Une erreur stupide : en 1999, la sonde Mars Climate Orbiter s'écrase sur Mars. Dans l'équipe de développement, les uns travaillaient en pieds et les autres en mètres. Ici, pas de problème d'arithmétique mais bien un vrai problème de tests.

Que faut-il en conclure ?

En conclusion de ces quelques exemples :

  • Pour travailler, il faut disposer sur les ordinateurs d'une arithmétique rapide, précise, de très grand dynamique et surtout normalisée pour garantir la portabilité des codes.
  • Il faut toujours traiter les exceptions susceptibles d'apparaître dans un code, pour les E/S, les calculs et les accès à l'OS. Souvenez-vous de la loi de Murphy : « tout ce qui est susceptible d'aller mal, ira mal».
  • En application de la loi de Murphy rappelée ci-dessus, les tests de robustesse et d'endurance sont absolument indispensables et doivent être imaginés en pensant au pire. Aucun système critique et a fortiori hautement critique ne devrait être mis en service sans avoir été torturé par des tests aussi complets que l'on peut imaginer. Les négliger ou les bâcler, sous quelque prétexte que ce soit, est irresponsable. Souvent des vies humaines en dépendent : parlez-en aux familles des passagers de deux Boeing 737 Max...