urSovngarde Le coop pour Skyrim VR
← Toutes les entrées

Lire un crash sans débogueur

Quand urSovngarde plante, le dump est inutile d’une façon très précise : il montre un module, environ 90 Mo, nommé SkyrimTogetherVR.exe. Le code du jeu et le nôtre sont tous les deux dedans. Les noms de modules ne peuvent pas les séparer, parce que pour Windows il n’y en a qu’un.

Nous avons passé plusieurs heures le 27 septembre à essayer de faire charger le PDB de cette image par dbghelp. Il ne le fera pas. SymLoadModuleEx signale le module comme différé, puis déclare introuvable chaque fonction pourtant connue. Cela ne vaut pas la peine d’être retenté, et cette entrée existe en partie pour que la prochaine personne, probablement l’un de nous, dans deux mois, ne le fasse pas.

Ce qui marche : la table des symboles de l’éditeur de liens

Code/immersive_launcher/xmake.lua passe /MAP, ce qui produit build/windows/x64/release/SkyrimTogetherVR.map. Cette table ne liste que nos symboles. Donc une adresse qu’elle nomme est à nous, et toute l’image du jeu tient dans un seul symbole appelé ?game_seg@@3PAEA.

Ce seul fait est la base entière de l’outillage de crash. Trois outils en sont sortis, du moins cher au plus lourd :

explain-crash.py lit le dump de registres que le client écrit dans tp_client.log et nomme les fonctions. Pas besoin de fichier dump, juste le log et l’exe et le PDB correspondants.

explain-dump.py lit un vrai .dmp. Il affiche l’exception, les registres, la fonction dans laquelle se trouvait Rip, puis l’anneau RecentDeletes : les 32 dernières copies distantes supprimées par ce client, ce qui détenait encore une revendication sur chacune, et si un registre en contient une actuellement.

Une ligne MATCH signifie que le code fautif détenait un acteur que nous avions supprimé, et que le chemin de destruction est la cause. NO MATCH signifie que non, et la recherche se déplace ailleurs. Cette seule distinction est la raison d’être de l’outil.

minidump.py est la couche en dessous, pour quand la question est simplement « est-ce que quoi que ce soit là-dedans est à nous ».

Le piège au milieu

La table doit venir de la build qui a planté.

Une table périmée n’échoue pas. Elle nomme les mauvaises fonctions, lit les mauvaises adresses, et a l’air parfaitement plausible en le faisant. Lancez une table actuelle contre un dump du 13 septembre et elle annoncera avec aplomb « 0 suppressions d’acteurs enregistrées pour cette session », pour une build écrite deux semaines avant l’existence de RecentDeletes.

explain-dump.py compare désormais l’horodatage de la table à celui du module dans le dump et refuse plutôt que de deviner. Si vous utilisez minidump.py ou mapsym.py directement, cette vérification est à votre charge.

Et une chose simplement impossible

L’exécutable du jeu sur le disque est chiffré par Steam. Une adresse à l’intérieur de ?game_seg@@3PAEA ne peut pas être désassemblée hors ligne. Nommer un appelant inconnu côté jeu demande soit un hook en jeu, soit la base d’adresses. Il n’y a pas de troisième option, et un après-midi passé à en chercher une est un après-midi.

Bordeciel est un grand pays à traverser seul

Gratuit, open source, et ça tourne sur la liste de mods que vous avez déjà.