Partager via


Choix des symboles publics à supprimer

PDBCopy fournit les options -f et -F afin que vous puissiez supprimer un ensemble arbitraire de symboles publics d’un fichier de symboles dépouillés, en laissant uniquement les symboles auxquels votre audience doit accéder pour effectuer son débogage.

Une utilisation courante de PDBCopy consiste à créer une version spéciale de votre fichier de symboles à utiliser par Microsoft dans son programme OCA (Online Crash Analysis). OCA peut désigner certaines fonctions comme inertes, ce qui signifie que si la fonction est trouvée sur la trace de pile, elle est ignorée. Une fonction est généralement déclarée inerte s’il s’agit simplement d’un wrapper ou d’une fonction « pass-through » qui n’effectue aucun calcul significatif. Si une telle fonction est trouvée sur la pile dans une analyse des défaillances, on peut supposer que cette fonction elle-même n’était pas en faute et qu’elle a tout au plus transmis des données non valides ou endommagées qu’elle a reçues des routines précédemment sur la pile. En ignorant ces fonctions, OCA peut mieux déterminer la cause réelle de l’erreur ou de l’altération.

Naturellement, toute fonction que vous souhaitez déclarer « inerte » doit être incluse dans la table de symboles publics du fichier de symboles utilisé par OCA. Toutefois, ce ne sont pas les seules fonctions qui doivent être incluses, comme le montre l’exemple suivant.

Supposons que vous écriviez un pilote Windows et que vous utilisiez PDBCopy pour supprimer tous les symboles publics de son fichier de symboles, à l’exception de FunctionOne et FunctionSix, deux fonctions inertes. Vous vous attendez à ce que si FunctionOne ou FunctionSix sont trouvés sur la pile après un plantage, ils seront ignorés par OCA. Si une autre partie de votre pilote se trouve sur la pile, Microsoft vous fournira l’adresse mémoire correspondante et vous pouvez utiliser l’adresse pour déboguer votre pilote.

Toutefois, supposons que votre pilote occupe la mémoire dans la disposition suivante :

Adresse Contenu de la mémoire

0x1000

Adresse de base du module

0x2000

Début de FunctionOne

0x203F

Fin de FunctionOne

0x3000

Début de FunctionSix

0x305F

Fin de FunctionSix

0x7FFF

Fin du module en mémoire

Si le débogueur trouve une adresse sur la pile, il sélectionne le symbole avec l’adresse inférieure suivante. Étant donné que la table de symboles publics contient l’adresse de chaque symbole, mais aucune information de taille, il n’existe aucun moyen pour le débogueur de savoir si une adresse se trouve réellement dans les limites d’un symbole spécifique.

Par conséquent, si une erreur se produit à l’adresse 0x2031, le débogueur exécuté par Microsoft OCA identifie correctement l’erreur comme étant située dans FunctionOne. Étant donné qu’il s’agit d’une fonction inerte, le débogueur continue de parcourir la pile pour trouver la cause de l’incident.

Toutefois, si une erreur se produit à 0x2052, le débogueur correspond toujours à cette adresse à FunctionOne, même si elle se trouve au-delà de la fin réelle de cette fonction (0x203F).

Par conséquent, vous devez inclure dans votre fichier de symboles supprimé non seulement les fonctions que vous souhaitez exposer, mais également les symboles qui suivent immédiatement ces fonctions. Dans cet exemple, vous souhaitez exposer FunctionOne, FunctionTwo, FunctionSix et FunctionSeven :

Adresse Contenu de la mémoire

0x1000

Adresse de base du module

0x2000

Début de FunctionOne

0x203F

Fin de FunctionOne

0x2040

Début de FunctionTwo

0x3000

Début de FunctionSix

0x305F

Fin de FunctionSix

0x3060

Début de FunctionSeven

0x7FFF

Fin du module en mémoire

Si vous incluez ces quatre fonctions dans le fichier de symboles supprimés, l’analyse Microsoft OCA ne traitera pas par erreur l’adresse 0x2052 dans le cadre de FunctionOne. Dans cet exemple, il suppose que cette adresse fait partie de FunctionTwo, mais cela n’est pas important, car vous n’avez pas inscrit FunctionTwo auprès d’OCA en tant que fonction inerte. L’important est que l’adresse 0x2052 soit reconnue comme ne relevant pas d’une fonction inerte. Par conséquent, OCA reconnaîtra cela comme une erreur significative au sein de votre pilote et pourra vous informer de l’erreur.

Si vous ne souhaitez pas rendre publics les noms des fonctions qui suivent chaque fonction inerte, vous pouvez insérer des fonctions sans importance dans votre code après chaque fonction inerte afin que les noms de ces fonctions puissent être inclus dans votre fichier de symboles publics. Veillez à vérifier que ces fonctions ajoutées suivent bien vos fonctions inertes dans l’espace d’adressage de votre binaire, car certaines routines d’optimisation peuvent modifier cela, voire supprimer complètement certaines fonctions.