4 points par GN⁺ 2025-09-18 | 1 commentaires | Partager sur WhatsApp
  • Confirmation de l’apparition d’un crash du jeu causé par un débordement de variable dans le moteur de DOOM
  • Expérience menée avec DOOM exécuté pendant 2,5 ans dans un environnement d’utilisation réel
  • À mesure que la valeur de la variable continuait d’augmenter, elle a fini par atteindre un overflow, provoquant l’arrêt du jeu au moment prévu
  • L’expérience a été réalisée dans un environnement d’exécution automatique de longue durée à l’aide d’un PDA et d’un UPS DIY
  • Ce test prouve qu’un problème théorique peut aussi se produire concrètement dans la réalité

Contexte et motivation de l’expérience

  • En lisant, il y a environ deux ans et demi, un article sur la structure du moteur de DOOM et son mode de fonctionnement, l’auteur a remarqué que la variable utilisée pour suivre l’exécution des démos continuait d’augmenter au début de chaque démo
  • Cette variable est comparée à la valeur précédente, mais comme elle augmente de façon répétée, elle comporte à terme un risque intrinsèque d’overflow
  • Dans un environnement d’usage ordinaire, il est difficile d’atteindre cette situation d’overflow, mais l’auteur a décidé de vérifier lui-même combien de temps cela prendrait réellement

Méthode et déroulement de l’expérience

  • Un calcul simple a permis d’estimer qu’il faudrait environ 2 ans et demi de runtime avant qu’un overflow ne se produise
  • Pour le vérifier concrètement, l’auteur a installé DOOM sur un PDA, puis l’a alimenté avec un UPS DIY utilisant des batteries 18650
  • L’appareil a été connecté au port USB d’un routeur afin de maintenir en continu une alimentation en 5V
  • Après avoir configuré le système pour qu’il fonctionne en continu dans un environnement de recharge automatique, il a été laissé tourner presque tout le temps sans surveillance

Survenue du crash et résultats

  • Environ deux ans et demi après le début de l’expérience, une notification pop-up est apparue à l’écran de l’appareil
  • Comme prévu, DOOM est passé dans un état de crash dur provoqué par l’overflow
  • Les résultats de l’expérience démontrent qu’un arrêt du jeu causé par un overflow de variable peut effectivement se produire sur du matériel réel et dans un environnement logiciel réel

Conclusion et implications

  • L’expérience souligne l’importance de prêter attention aux variables qui s’accumulent et augmentent sur de longues durées en programmation
  • Elle confirme de manière expérimentale qu’un problème d’overflow considéré comme purement théorique peut réellement se produire dans la pratique
  • Elle alerte aussi sur les défauts cachés dans le code legacy ou dans les logiciels conçus pour fonctionner pendant de longues périodes

1 commentaires

 
GN⁺ 2025-09-18
Avis Hacker News
  • Il y a environ un an, en examinant le système de timer de Crash Bandicoot, quelqu’un a découvert que dans Crash 3, une valeur de type int32 continue d’augmenter et n’est réinitialisée qu’à la mort du personnage. Après 2,26 ans de fonctionnement continu, un overflow se produit. Le temps devient alors « négatif » et le jeu se casse de façons assez drôles. Une vidéo a été réalisée à ce sujet : lien YouTube

    • Dans Final Fantasy 9, pour obtenir une arme précise, il faut atteindre une zone de fin de jeu en moins de 12 heures (10 heures dans la version européenne), mais à cause d’un bug, on peut aussi l’obtenir en laissant le jeu tourner pendant 2 ans jusqu’à l’overflow du timer. Même en attendant tranquillement, on atteint l’objectif. Explication détaillée

    • C’est amusant de constater que dans ta vidéo, tu n’as jamais fait le moindre jeu de mots avec « crash ». Tu aurais même pu appeler le gel du jeu un crash, dommage.

    • Je me demande s’il était courant d’utiliser par défaut des signed integer pour suivre un timer. Avec un type unsigned, le délai avant overflow aurait été deux fois plus long, donc je me demande pourquoi ce choix a été fait.

    • Je pense que beaucoup de jeux étaient conçus comme ça. SotN a aussi un timer global. Sur un système 32 bits, pour un jeu censé tourner quelques mois, au pire quelques années, personne ne voyait l’intérêt de tester le passage de plusieurs années. À l’époque, personne n’imaginait vraiment que son logiciel serait hacké, disséqué et rétroconçu. Nous-mêmes, dans nos programmes du quotidien, nous ne pensons pas tant que ça à ce genre de choses.

    • Le véritable déblocage de Time Twister.

  • C’est le genre de situation qui peut rendre le jeu injouable, et j’aimerais vraiment que quelqu’un le corrige. Doom est un jeu formidable, et j’y reviens toujours tous les quelques ans. Le reboot de 2016 était très fun, mais les titres sortis ensuite m’ont moins plu.

    • Il existe une communauté pour les gens qui préfèrent le gameplay à l’ancienne de Doom : r/boomershooters

    • Pareil pour moi. Le design metroidvania et la structure en hub central des titres récents ne retrouvent pas la sensation d’avant. Je préfère la progression simple : courir, tuer des ennemis, trouver des secrets et passer au niveau suivant.

    • Moi aussi, surtout avec le mode brutality que j’adore.

    • Fait intéressant : Doom appartient désormais à Microsoft, tout comme Quake, StarCraft, WarCraft, Overwatch, tous les jeux d’aventure d’Infocom et Sierra, ainsi que Halo. Microsoft essaye de mettre la main sur l’essentiel de la propriété intellectuelle du jeu PC depuis 1996, donc on peut dire qu’ils ont presque atteint leur but.

    • L’opus de 2016 est le meilleur FPS solo auquel j’ai joué, et le seul comparable pour moi, c’est Titan Fall 2.

  • Je me demande si le matériel dispose d’une fonction pour piéger les overflow. En lisant un article sur le fonctionnement du moteur de Doom, j’ai vu qu’une variable de suivi des démos continue d’augmenter même quand la démo suivante démarre. Cette variable est comparée à une seconde variable qui stocke la valeur précédente. Je me demande pourquoi le vrai jeu finit par crasher.

    • En C, le signed overflow est un comportement indéfini, donc le résultat est imprévisible. Mais ici, comme le comportement semble identique quelle que soit la plateforme ou le compilateur, ça n’a pas l’air d’être ça. D’après l’article (TFA), cette variable est comparée à sa valeur précédente, mais le code n’avait visiblement pas prévu qu’un cas new < old puisse se produire. Cela peut facilement entraîner des bugs comme une corruption de pile. En C, il est tout à fait possible de déclencher tranquillement un comportement indéfini, par exemple lorsqu’une fonction qui ne retourne rien atteint un chemin où elle devrait renvoyer une valeur.
  • Il faut être reconnaissant d’avoir connu la cause du bug à l’avance. On aurait aussi pu se rendre compte au bout de 2,5 ans : « mince, j’ai oublié d’activer les logs de debug ».

  • DOOM a crashé avant Windows CE.

    • Ce qui m’impressionne le plus, c’est qu’une application ait pu tourner en continu pendant 2,5 ans sur un PDA. J’ai de gros doutes sur le fait qu’on puisse faire pareil aujourd’hui sur du matériel récent, sans coupure d’Internet.

    • C’est vraiment un record impressionnant.

  • Le site semble être tombé à cause d’un trop grand nombre d’accès, donc voici un lien archive.org : copie archive.org. Malheureusement, toute la mise en forme du site n’a pas été conservée, mais le texte est toujours là.

  • 2038 promet d’être une année intéressante.

    • Beaucoup de gens négligent le problème NTP de 2036. C’est là que la vraie fête commencera.

    • 2038 me paraît bien plus proche que l’époque du y2k.

    • Il reste 13 ans pour passer aux int 64 bits ou pour faire évoluer time_t vers un type long long. Beaucoup d’équipements embarqués et de systèmes fermés en fin de support demanderont une attention particulière. L’OpenFirmware de mon ancien SunServer 600MP avait le même problème. Heureusement, ce n’est plus quelque chose dont j’ai à me soucier.

    • Résoudre ce problème, c’est mon plan retraite.

  • Aucun testeur que je connaisse ne ferait un test à ce niveau-là. Rien qu’hier, sur le système sur lequel je travaille, j’ai déjà dû attendre plus de cinq fois un timeout de 30 secondes pour vérifier la gestion d’erreur, et c’était extrêmement agaçant.

  • Il y a eu un bug similaire autrefois dans Windows NT 4. C’était lié à un compteur haute précision servant à mesurer l’uptime du système. Avant le Service Pack 3 (ou 2), on avait programmé un redémarrage automatique chaque 1er du mois via le scheduler ; sinon, le système crashait après environ 42 jours d’uptime. Même Microsoft n’imaginait pas qu’un OS serveur puisse tourner aussi longtemps sans interruption.

    • Tu parles peut-être du problème mentionné dans ce lien ? Ou bien il y avait un bug distinct dans NT 4 ?
  • Encore une fois, bravo à l’équipe d’id Software. Si le jeu avait été développé aujourd’hui de manière plus classique, il serait probablement mort bien avant les 2 ans à cause de la fragmentation mémoire ou de fuites mémoire.