Monday, August 30, 2021

Trouver le thread fautif

Bon, ce coup-ci, j'étais sur un autre cas de figure: le programme fautif est toujours occupé à tourner, mais un de ses threads est mort, causant une attente infinie dans un autre. Je sais demander un .dmp au Task Manager, ouvrir le .dmp en question sur la machine de dev avec les bons chemins pour les serveurs de symboles (eh oui, moi du futur: tu as oublié mais sous Windows, il n'y a pas de .elf de debugging: les symboles de debug sont d'office dans un fichier séparé) et parcourir la liste des threads en espérant y voir apparaître KERNELBASE!UnhandledExceptionFilter dans la pile d'appels correspondante. 

Ce n'est pas trop dur de repérer l'adresse du crash, mais c'est une autre histoire de connaître l'état des registres au moment du plantage.

Il devrait y avoir une extension de windbg pour gérer ça, mais le site qui la proposait a disparu dans les limbes du temps. Par contre si je parviens à deviner où elle se trouve, la structure EXCEPTION_POINTERS devrait nous fournir toutes les infos nécessaires pour continuer à debugger.

Eh bien voilà: cette structure est produite dans le stack frame (les variables locales, NdT) de ntdll!_C_specific_handler (encadré en rouge dans la capture ci-contre) et référencée dans le stack frame de UnhandledExceptionFilter. J'ai utilisé les adresses renseignées par la colone 'Child-SP' et retracé ça à la main dans Gimp, hein. Ici, un seul candidat: 0x16bee7c0.

Reste à s'assurer que c'est bien la bonne adresse. Je peux utiliser la commande windbg dt 0x16bee7c0 EXCEPTION_POINTERS pour le coup: si je suis dans le bon, elle me donnera deux pointeurs valides

En cliquant sur le 'exception record', on devrait avoir un code valide (type 0xc000000*) et une adresse qui correspond à notre fonction fautive (aussi renseignée comme adresse de retour pour KiUserExceptionDispatch, soit ici à l'intérieur de MoveSmall).

No comments: