Journal Unvanquished: un patch de dernière minute pour la 0.51 et une conférence ce dimanche

9
21
nov.
2020

Sommaire

Préambule: Ce journal traite du jeu libre Unvanquished, mélant stratégie et vue à la première personne. Ce journal est une traduction de ce billet sur le blog officiel.

Salut à tous, certaines personnes ont rapporté que notre version 0.51 précompilée a quelques problèmes sur les distributions Linux récentes. Une façon simple de patcher votre jeu téléchargé est donné juste après. Il y a aussi une conférence à voir ce dimanche en ligne!

Une conférence ce dimanche pour Debian

Nous participons à la « MiniDebConf en ligne Édition jeu vidéo » hébergée par Debian, qui a par ailleurs déjà accueilli vv222< aujourd’hui pour présenter ./play.it.

Logo MDCO Gaming Edition

Donc, ce dimanche 22 novembre (demain) à 19:30 UTC (20:30 heure française), il y aura une conférence de 45 minutes intitulée :

Construire une communauté en tant que service : comment cesser de souffrir de « ce code est censé être forké ».

Voici la quatrième de couverture :

Il est connu que les précédents moteurs id Tech ont vu leur code source ouvert lors qu’ils furent remplacés et donc non rentable. Bien que cela fut un énorme apport à l’humanité, les développeurs de jeux souffrent encore aujourd’hui des choix de conception et de l’état d’esprit induit par le fait qu’une telle base de code était destinée à mourir. 20 ans plus tard, nous nous concentrerons sur l’héritage de l'id Tech 3, sur la manière dont le marché, les communautés open source et les pratiques de développement de jeux ont évolué, et nous embarquerons dans l’aventure de la transition nécessaire depuis des vidages de dépôt de code mort à un écosystème en tant que service.

Je serai le conférencier, la diffusion en direct est ici. C’est en anglais et mon accent français va piquer un peu. =)

Si vous manquez le rendez-vous, pas d’inquiétude ! La vidéo sera disponible en ligne après la diffusion, et une transcription complète sera publiée, en anglais d’abord, puis en français ici.

Comment patcher votre jeu si vous rencontrez des problèmes à le faire tourner sur une distribution Linux récente

Le probème a été confirmé sur Fedora, Arch Linux, Debian testing (Debian stable n’est pas affectée) et dérivés. Tandis que les distributions font leur mises à jour, d’autres sont susceptibles de tomber en panne.

Le symptôme est facile à remarquer : le jeux fait une erreur de segmentation immédiatement au démarrage avant de pouvoir faire quoique ce soit d’autre. Oui, c’est vraiment grave.

TL;DR: Si vous rencontrez le problème, voici un moyen facile de télécharger un patcheur:

wget http://dl.unvanquished.net/hotfix/unvanquished_0.51.1_patch
chmod +x unvanquished_0.51.1_patch

Après ça vous pouvez lancer le jeu de cette manière :

./unvanquished_0.51.1_patch daemon

Cela marchera sans rien faire de plus si vous aviez téléchargé et installé le jeu avec notre utilitaire de mise à jour. Si vous aviez utilisé l’archive zip universelle, le plus facile pour vous est d’enregistrer le patcheur juste à côté du binaire daemon et le lancer depuis ce dossier.

Le patcheur est un lanceur qui patche une copie du binaire puis l’exécute (et laisse non-modifié celui qui a des problèmes). Donc d’ici que la version 0.52 soit sortie, vous pouvez utiliser ce simple lanceur.

Vous pouvez aussi passer daemonded en paramètre pour patcher et exécuter le serveur, vous pouvez ensuite passer toutes les ordinaires options de ligne de commande du jeu.

Il est aussi possible de recompiler les binaires, mais ça demande plus de travail et de notre côté on se concentre sur la version 0.52 à venir.

Ceux qui voudraient corriger définitivement leurs binaires peuvent faire ceci (mieux vaut faire une sauvegarde avant):

printf '\x8b\x74\x24\x20\x48\x31\xc0\x85\xf6\x0f\x94\xc0\xeb\x3f' \
| dd of=daemon bs=1 seek=2186551 count=14 conv=notrunc
printf '\x8b\x74\x24\x20\x48\x31\xc0\x85\xf6\x0f\x94\xc0\xeb\x3f' \
| dd of=daemonded bs=1 seek=738855 count=14 conv=notrunc

Plus de détails sur le problème, si vous aimez plonger en profondeur dans la matrice

patch de Dæmon

Le sortilège du patch de Dæmon dévoilé, en lisant la matrice sans décodeur.

Oui, c’est vraiment de la sorcellerie. Pour les geeky geeks, il y a ici quelques explications de la part de notre maître sorcier slipher:

Le crash est causé par une erreur ou une imperfection dans l’implémentation du concept d’« ABI double » dans la libstdc++. Pour ce bug, la classe appropriée pour la double ABI est std::error_category (qui a la double ABI parce qu’elle a une fonction membre retournant une std::string). Après ce commit, stdlibc++ définit deux versions de error_category. Pour les nouveaux binaires, les entête pointent vers la nouvelle version qui est définie dans un espace de nom en ligne (inline namespace) _v2. L’espace de nom en ligne modifie le nom des symboles dans le code compilé, tandis que le code source qui utilise error_category n’est pas modifié.

La version 0.51 a été apparemment construite avec GCC 4.9, ce qui est antérieur à l’introduction de la double ABI. Cela signifie qu’elle se retrouve liée aux symboles de compatibilité antérieure quand les bibliothèques partagées sont utilisées. Un binaire compilé avec GCC5 et suivant devrait avoir les entête pointant vers la nouvelle ABI, et ainsi éviter le problème (elle est liée à std::_V2::system_category() et évite de construire des objets de compatibilité antérieure). Il n’y a donc rien à faire pour éviter le problème dans les nouvelles versions (bien que de toute façon je supprime l’appel à default_error_condition, puisque ça ne fait pas sens de l’utiliser).

J’ai reproduit le crash en utilisant libstdc++.so.6.0.28; je pense que la libstdc++.so.6.0.21 devrait être la première version qui contient les modifications de double AABI et qui risque donc de se prendre le bug.

Et ici il donne encore plus d’explications :

Je doute qu’il y ait quoi que ce soit à faire dû côté de la libstdc++. Il est probablement impossible de produire un binaire qui peut fonctionner avec les deux ABI error_category, et la nouvelle est sortie depuis longtemps.

La conjecture de mon précédent commentaire selon laquelle cela dépend de la valeur aléatoire dans le registre RDX au moment de l’appel à error_category::equivalent (qui était censé être un appel à error_category::default_error_condition) était correcter. Sur Mageia, le RDX contenait une adresse lisible, tandis que sur Debian Buster, il en contenait 4.

Maintenant, error_category::default_error_condition est censé renvoyer une structure error_condition consistant en un code entier et un pointeur vers error_category. L’ABI dicte que le code entier va dans RAX et le pointeur dans RDX. error_category::equivalent retourne un booléen qui va dans RAX. Il retourne faux, après comparaison avec des déchets aléatoires. Et il se trouve que dans ce « build » de bibliothèque partagée, la dernière chose qui est mise dans RDX par error_category::equivalent est l’adresse de std::system_category(), une instance de error_category. Donc, par pure chance, une condition error_condition valide et correcte est retournée, et le train est de retour sur les rails.

Je pourrais faire un patch binaire pour dæmon 0.51 afin de contourner le problème en remplaçant quelques instructions dans CreateCrashDumpPath, si cela peut rendre service.

Ça rend vraiment service, donc il a écrit cette incantation de dd et vous pouvez la faire vous-même ou utiliser le patcheur.

Et vous pouvez toujours jouer à Unvanquished tout en attendant la version 0.52 !

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.