Partager via


Vérification des symboles

Les problèmes de symboles peuvent apparaître de différentes manières. Peut-être qu’une trace de pile montre des informations incorrectes ou ne parvient pas à identifier les noms des fonctions dans la pile. Ou peut-être qu’une commande de débogueur n’a pas pu comprendre le nom d’un module, d’une fonction, d’une variable, d’une structure ou d’un type de données.

Si vous pensez que le débogueur ne charge pas correctement les symboles, vous pouvez effectuer plusieurs étapes pour examiner ce problème.

Tout d’abord, utilisez la commande lm (List Loaded Modules) pour afficher la liste des modules chargés avec des informations de symbole. La forme la plus utile de cette commande est la suivante :

0:000> lml 

Si vous utilisez WinDbg, le débogage | La commande de menu Modules vous permet également de voir ces informations.

Prêtez une attention particulière aux notes ou abréviations que vous pouvez voir dans ces affichages. Pour une interprétation de ceux-ci, consultez Abréviations d’état des symboles.

Si vous ne voyez pas les fichiers de symboles appropriés, la première chose à faire consiste à case activée le chemin du symbole :

0:000> .sympath
Current Symbol Path is: d:\MyInstallation\i386\symbols\retail

Si le chemin de votre symbole est incorrect, corrigez-le. Si vous utilisez le débogueur de noyau, assurez-vous que votre %WINDIR% local n’est pas sur le chemin de votre symbole.

Ensuite, rechargez les symboles à l’aide de la commande .reload (Recharger le module) :

0:000> .reload ModuleName 

Si le chemin de votre symbole est correct, vous devez activer le mode bruyant afin de voir les fichiers de symboles que dbghelp est en train de charger. Rechargez ensuite votre module. Pour plus d’informations sur l’activation du mode bruyant, consultez Définition des options de symbole .

Voici un exemple de rechargement « bruyant » des symboles Microsoft Windows :

kd> !sym noisy
kd> .reload nt
 1: Kernel Version 2081 MP Checked
 2: Kernel base = 0x80400000 PsLoadedModuleList = 0x80506fa0
 3: DBGHELP: FindExecutableImageEx-> Looking for D:\MyInstallation\i386\ntkrnlmp.exe...mismatched timestamp
 4: DBGHELP: No image file available for ntkrnlmp.exe
 5: DBGHELP: FindDebugInfoFileEx-> Looking for
 6: d:\MyInstallation\i386\symbols\retail\symbols\exe\ntkrnlmp.dbg... no file
 7: DBGHELP: FindDebugInfoFileEx-> Looking for
 8: d:\MyInstallation\i386\symbols\retail\symbols\exe\ntkrnlmp.pdb... no file
 9: DBGHELP: FindDebugInfoFileEx-> Looking for d:\MyInstallation\i386\symbols\retail\exe\ntkrnlmp.dbg... OK
10: DBGHELP: LocatePDB-> Looking for d:\MyInstallation\i386\symbols\retail\exe\ntkrnlmp.pdb... OK
11: *** WARNING: symbols checksum and timestamp is wrong 0x0036a4ea 0x00361a83 for ntkrnlmp.exe

Le gestionnaire de symboles recherche d’abord une image qui correspond au module qu’il tente de charger (lignes trois et quatre). L’image elle-même n’est pas toujours nécessaire, mais si une image incorrecte est présente, le gestionnaire de symboles échoue souvent. Ces lignes indiquent que le débogueur a trouvé une image à D:\MyInstallation\i386\ntkrnlmp.exe, mais que l’horodatage ne correspondait pas. Étant donné que l’horodatage ne correspond pas, la recherche continue. Ensuite, le débogueur recherche un fichier .dbg et un fichier .pdb qui correspondent à l’image chargée. Il s’agit des lignes 6 à 10. La ligne 11 indique que même si les symboles ont été chargés, l’horodatage de l’image ne correspondait pas (autrement dit, les symboles étaient incorrects).

Si la recherche de symboles a rencontré un échec catastrophique, vous voyez un message au format :

ImgHlpFindDebugInfo(00000000, module.dll, c:\MyDir;c:\SomeDir, 0823345, 0) failed

Cela peut être dû à des éléments tels que des défaillances du système de fichiers, des erreurs réseau et des fichiers .dbg endommagés.

Diagnostic des erreurs de chargement de symboles

En mode bruyant, le débogueur peut imprimer des codes d’erreur lorsqu’il ne peut pas charger un fichier de symboles. Les codes d’erreur des fichiers .dbg sont répertoriés dans winerror.h. Les codes d’erreur .pdb proviennent d’une autre source et les erreurs les plus courantes sont imprimées en texte anglais brut.

Voici quelques codes d’erreur courants pour les fichiers .dbg de winerror.h :

0xB
ERROR_BAD_FORMAT

0x3
ERROR_PATH_NOT_FOUND

0x35
ERROR_BAD_NETPATH

Il est possible que le fichier de symboles ne puisse pas être chargé en raison d’une erreur de mise en réseau. Si vous voyez ERROR_BAD_FORMAT ou ERROR_BAD_NETPATH et que vous chargez des symboles à partir d’un autre ordinateur sur le réseau, essayez de copier le fichier de symboles sur votre ordinateur hôte et placez son chemin dans le chemin de votre symbole. Essayez ensuite de recharger les symboles.

Vérification de votre chemin de recherche et de vos symboles

Let « c :\MyDir ; c :\SomeDir » représentent le chemin de votre symbole. Où devez-vous rechercher des informations de débogage ?

Dans les cas où le fichier binaire a été supprimé des informations de débogage, telles que les builds gratuites de Windows, recherchez d’abord un fichier .dbg aux emplacements suivants :

c:\MyDir\symbols\exe\ntoskrnl.dbg
c:\SomeDir\symbols\exe\ntoskrnl.dbg
c:\MyDir\exe\ntoskrnl.dbg
c:\SomeDir\exe\ntoskrnl.dbg
c:\MyDir\ntoskrnl.dbg
c:\SomeDir\ntoskrnl.dbg
current-working-directory\ntoskrnl.dbg

Ensuite, recherchez un fichier .pdb aux emplacements suivants :

c:\MyDir\symbols\exe\ntoskrnl.pdb
c:\MyDir\exe\ntoskrnl.pdb
c:\MyDir\ntoskrnl.pdb
c:\SomeDir\symbols\exe\ntoskrnl.pdb
c:\SomeDir\exe\ntoskrnl.pdb
c:\SomeDir\ntoskrnl.pdb
current-working-directory\ntoskrnl.pdb

Notez que dans la recherche du fichier .dbg, le débogueur effectue une recherche dans les répertoires MyDir et SomeDir, mais pas dans la recherche .pdb.

Windows XP et les versions ultérieures de Windows n’utilisent pas de fichiers de symboles .dbg. Pour plus d’informations, consultez Symboles et fichiers de symboles.

Builds incompatibles

L’un des problèmes les plus courants lors du débogage des échecs sur une machine qui est souvent mise à jour est l’incompatibilité des symboles provenant de différentes builds. Trois causes courantes de ce problème sont : pointer vers des symboles pour une build incorrecte, utiliser un binaire généré en privé sans les symboles correspondants et utiliser le niveau d’abstraction matérielle uniprocesseur (HAL) et les symboles de noyau sur une machine multiprocesseur. Les deux premiers sont simplement une question de correspondance entre vos fichiers binaires et vos symboles ; Le troisième peut être corrigé en renommant hal*.dbg et ntkrnlmp.dbg en hal.dbg et ntoskrnl.dbg.

Pour savoir quelle build de Windows est installée sur l’ordinateur cible, utilisez la commande vertarget (Afficher la version de l’ordinateur cible) :

kd> vertarget 
Windows XP Kernel Version 2505 UP Free x86 compatible
Built by: 2505.main.010626-1514
Kernel base = 0x804d0000 PsLoadedModuleList = 0x80548748
Debug session time: Mon Jul 02 14:41:11 2001
System Uptime: 0 days 0:04:53 

Test des symboles

Le test des symboles est plus difficile. Cela implique de vérifier une trace de pile sur le débogueur et de voir si la sortie de débogage est correcte. Voici un exemple à essayer :

kd> u videoprt!videoportfindadapter2
Loading symbols for 0xf2860000     videoprt.sys ->   videoprt.sys

VIDEOPRT!VideoPortFindAdapter2:
f2856f42 55               push    ebp
f2856f43 8bec             mov     ebp,esp
f2856f45 81ecb8010000     sub     esp,0x1b8
f2856f4b 8b4518           mov     eax,[ebp+0x18]
f2856f4e 53               push    ebx
f2856f4f 8365f400         and     dword ptr [ebp-0xc],0x
f2856f53 8065ff00         and     byte ptr [ebp-0x1],0x0
f2856f57 56               push    esi

La commande u désassemble la chaîne videoportfindadapter dans videoprt.sys. Les symboles sont corrects sur le débogueur, car les commandes de pile courantes telles que push et mov s’affichent sur la pile. La plupart des fonctions commencent par une opération d’ajout, de sous ou de push à l’aide du pointeur de base (ebp) ou du pointeur de pile (esp).

C’est généralement évident quand les symboles ne fonctionnent pas correctement. Glintmp.sys n’a pas de symboles dans cet exemple, car une fonction n’est pas répertoriée en regard de Glintmp :

kd> kb
Loading symbols for 0xf28d0000     videoprt.sys ->   videoprt.sys
Loading symbols for 0xf9cdd000      glintmp.sys ->   glintmp.sys
*** ERROR: Symbols could not be loaded for glintmp.sys
ChildEBP RetAddr  Args to Child
f29bf1b0 8045b5fa 00000001 0000a100 00000030 ntoskrnl!RtlpBreakWithStatusInstruction
f29bf1b0 8044904e 00000001 0000a100 00000030 ntoskrnl!KeUpdateSystemTime+0x13e
f29bf234 f28d1955 f9b7d000 ffafb2dc f9b7d000 ntoskrnl!READ_REGISTER_ULONG+0x6
f29bf248 f9cde411 f9b7d000 f29bf2b0 f9ba0060 VIDEOPRT!VideoPortReadRegisterUlong+0x27
00000002 00000000 00000000 00000000 00000000 glintMP+0x1411 [No function listed.] 

Les symboles de build incorrects ont été chargés pour cette trace de pile. Notez qu’aucune fonction n’est répertoriée pour les deux premiers appels. Cette trace de pile ressemble à un problème avec win32k.sys rectangles de dessin :

1: kd> 
1: kd> kb                      [Local        9:50 AM]
Loading symbols for 0xf22b0000       agpcpq.sys ->   agpcpq.sys
*** WARNING: symbols checksum is wrong 0x0000735a 0x00000000 for agpcpq.sys
*** ERROR: Symbols could not be loaded for agpcpq.sys
Loading symbols for 0xa0000000       win32k.sys ->   win32k.sys
*** WARNING: symbols checksum is wrong 0x00191a41 0x001995a9 for win32k.sys
ChildEBP RetAddr  Args to Child
be682b18 f22b372b 82707128 f21c1ffc 826a70f8 agpCPQ+0x125b [No function listed.]
be682b4c a0140dd4 826a72f0 e11410a8 a0139605 agpCPQ+0x372b [No function listed.]
be682b80 a00f5646 e1145100 e1cee560 e1cee560 win32k!vPatCpyRect1_6x6+0x20b
00000001 00000000 00000000 00000000 00000000 win32k!RemoteRedrawRectangle+0x32 

Voici la trace de pile correcte. Le problème est vraiment avec AGP440.sys. Le premier élément apparaissant sur une trace de pile est généralement en cause. Notez que l’erreur rectangle win32k.sys a disparu :

1: kd> kb                      [Local        9:49 AM]
ChildEBP RetAddr  Args to Child
be682b18 f22b372b 82707128 f21c1ffc 826a70f8 agpCPQ!AgpReleaseMemory+0x88
be682b30 f20a385c 82703638 e183ec68 00000000 agpCPQ!AgpInterfaceReleaseMemory+0x8b
be682b4c a0140dd4 826a72f0 e11410a8 a0139605 VIDEOPRT!AgpReleasePhysical+0x44
be682b58 a0139605 e1cee560 e11410a8 a00e5f0a win32k!OsAGPFree+0x14
be682b64 a00e5f0a e1cee560 e11410a8 e1cee560 win32k!AGPFree+0xd
be682b80 a00f5646 e1145100 e1cee560 e1cee560 win32k!HeapVidMemFini+0x49
be682b9c a00f5c20 e1cee008 e1cee008 be682c0c win32k!vDdDisableDriver+0x3a
be682bac a00da510 e1cee008 00000000 be682c0c win32k!vDdDisableDirectDraw+0x2d
be682bc4 a00da787 00000000 e1843df8 e1843de8 win32k!PDEVOBJ__vDisableSurface+0x27
be682bec a00d59fb 00000000 e1843de8 00000000 win32k!PDEVOBJ__vUnreferencePdev+0x204
be682c04 a00d7421 e1cee008 82566a98 00000001 win32k!DrvDestroyMDEV+0x30
be682ce0 a00a9e7f e1843e10 e184a008 00000000 win32k!DrvChangeDisplaySettings+0x8b3
be682d20 a008b543 00000000 00000000 00000000 win32k!xxxUserChangeDisplaySettings+0x106
be682d48 8045d119 00000000 00000000 00000000 win32k!NtUserChangeDisplaySettings+0x48
be682d48 77e63660 00000000 00000000 00000000 ntkrnlmp!KiSystemService+0xc9 

Commandes et extensions utiles

Les commandes et extensions suivantes peuvent être utiles pour suivre les problèmes de symboles :

lm (Liste des modules chargés)
Répertorie tous les modules et donne la status de chargement de tous les symboles de ces modules.

!dh image-header-base
Affiche les informations d’en-tête d’une image chargée à partir de image-header-base.

.reload /n
Recharge tous les symboles du noyau.

.reload [image-name]
(CDB ou WinDbg uniquement) Recharge les symboles pour le nom de l’image. Si aucun nom d’image n’est spécifié, recharge les symboles pour toutes les images. (Il est nécessaire de recharger les symboles une fois que le chemin du symbole a été modifié.)

!sym bruyant
Active le mode détaillé pour les chargements de symboles. Vous pouvez l’utiliser pour obtenir des informations sur les charges de module. Pour plus d’informations , consultez Définition des options de symbole.

.sympath [new-symbol-path]
Définit un nouveau chemin de symbole ou affiche le chemin d’accès au symbole actuel. Pour plus d’informations, consultez Chemin des symboles.

Si les symboles du noyau sont corrects, mais que vous n’obtenez pas de pile complète, les commandes suivantes peuvent également être utiles :

X*!
Cette opération répertorie les modules pour lesquels des symboles sont actuellement chargés. Cela est utile si les symboles du noyau sont corrects.

.reload /user
Cela tente de recharger tous les symboles en mode utilisateur. Cela est nécessaire lors de l’exécution du débogage du noyau si des symboles ont été chargés pendant l’exécution d’un processus et qu’une interruption s’est produite ultérieurement dans un autre processus. Dans ce cas, les symboles en mode utilisateur du nouveau processus ne seront pas chargés, sauf si cette commande est exécutée.

X wdmaud !*start\*
Cela répertorie uniquement les symboles du module wdmaud dont les noms contiennent la chaîne « start ». Cela a l’avantage de forcer le rechargement de tous les symboles dans wdmaud, mais n’affiche que ceux avec « start » dans ceux-ci. (Cela signifie une liste plus courte, mais étant donné qu’il y a toujours des symboles avec « début » dans ceux-ci, il y aura une vérification que le chargement a eu lieu.)

Une autre technique utile pour vérifier les symboles est le désassemblage du code. La plupart des fonctions commencent par une opération add, sub ou push utilisant le pointeur de base (ebp) ou le pointeur de pile (esp ou sp). Essayez de désassembler (fonction U) certaines des fonctions sur la pile (à partir du décalage zéro) pour vérifier les symboles.

Problèmes réseau et de port

Des problèmes se produisent avec les fichiers de symboles et lors de la connexion au débogueur. Voici quelques éléments à garder à l’esprit si vous rencontrez des problèmes :

  • Déterminez le port COM auquel le câble de débogage est connecté sur le système de test.

  • Vérifiez les paramètres boot.ini du système de test. Recherchez le commutateur /debug et case activée les paramètres de débit en bauds et de port COM.

  • Les problèmes réseau peuvent interférer avec le débogage si les fichiers de symboles sont accessibles via le réseau.

  • .dll et les fichiers .sys portant le même nom (par exemple , mga64.sys et mga64.dll) confondent le débogueur s’ils ne sont pas séparés dans les répertoires appropriés de l’arborescence de symboles.

  • Le débogueur de noyau n’aime pas toujours remplacer les fichiers de symboles de build par des fichiers de symboles privés. Doublez case activée le chemin du symbole et effectuez un fichier .reloadFileName sur le symbole qui se comporte mal. La commande !dlls est parfois utile.

Questions et idées fausses

Q: J’ai correctement chargé des symboles, mais la pile semble être incorrecte. Le débogueur est-il cassé ?

Un: Pas nécessairement. La cause la plus probable de votre problème est que vous avez des symboles incorrects. Suivez les étapes décrites dans cette section pour déterminer si vous avez chargé des symboles valides ou non. Ne partez pas du principe que, parce que certaines choses fonctionnent, vous avez des symboles valides. Par exemple, vous pouvez très bien exécuter dd nt !ntbuildnumber ou u nt ! KeInitializeProcess avec des symboles incorrects. Vérifiez qu’elles sont correctes à l’aide des procédures décrites ci-dessus.

Q: Le débogueur fonctionnera-t-il toujours avec des symboles incorrects ?

Un: Oui et non. Souvent, vous pouvez vous en tirer avec des symboles qui ne correspondent pas strictement. Par exemple, les symboles d’une build Windows précédente fonctionnent souvent dans certains cas, mais il n’existe aucune règle quant au moment où cela fonctionnera et quand il ne fonctionnera pas.

Q: Je suis arrêté dans le débogueur de noyau et je souhaite afficher les symboles de mon processus en mode utilisateur. Est-ce que je peux le faire ?

Un: Surtout. La prise en charge de ce scénario est médiocre, car le débogueur de noyau ne conserve pas suffisamment d’informations pour suivre les chargements des modules pour chaque processus, mais il existe une solution de contournement raisonnable. Pour charger des symboles pour un module en mode utilisateur, exécutez une commande .reload -user . Cela charge les modules en mode utilisateur pour le contexte actuel.

Q: Que signifie le message suivant ?

*** WARNING: symbols checksum and timestamp is wrong 0x0036d6bf 0x0036ab55 for ntkrnlmp.exe

Un: Cela signifie que vos symboles pour ntkrnlmp.exe sont incorrects.