syntaxe Pseudo-Register

Le débogueur prend en charge plusieurs pseudo-registres qui contiennent certaines valeurs.

Le débogueur définit des pseudo-registres automatiques sur certaines valeurs utiles. Les pseudo-registres définis par l’utilisateur sont des variables entières que vous pouvez écrire ou lire.

Tous les pseudo-registres commencent par un signe dollar ($). Si vous utilisez la syntaxe MASM, vous pouvez ajouter un signe at ( @ ) avant le signe dollar. Ce signe indique au débogueur que le jeton suivant est un registre ou un pseudo-registre, et non un symbole. Si vous omettez l’élément au signe, le débogueur répond plus lentement, car il doit rechercher l’ensemble de la table de symboles.

Par exemple, les deux commandes suivantes produisent la même sortie, mais la deuxième commande est plus rapide.

0:000> ? $exp
Evaluate expression: 143 = 0000008f
0:000> ? @$exp
Evaluate expression: 143 = 0000008f

S’il existe un symbole portant le même nom que le pseudo-registre, vous devez ajouter le signe at.

Si vous utilisez la syntaxe d’expression C++, le signe at ( @ ) est toujours requis.

La commande r (Registers) est une exception à cette règle. Le débogueur interprète toujours son premier argument comme un registre ou un pseudo-registre. (Un signe à l’heure n’est pas obligatoire ou autorisé.) S’il existe un deuxième argument pour la commande r , il est interprété en fonction de la syntaxe d’expression par défaut. Si la syntaxe d’expression par défaut est C++, vous devez utiliser la commande suivante pour copier le pseudo-registre $t 2 dans le pseudo-registre $t 1 .

0:000> r $t1 = @$t2

Pseudo-Registers automatique

Le débogueur définit automatiquement les pseudo-registres suivants.

Pseudo-registre Description

$ea

Adresse effective de la dernière instruction exécutée. Si cette instruction n’a pas d’adresse effective, le débogueur affiche « Erreur de registre incorrect ». Si cette instruction a deux adresses effectives, le débogueur affiche la première adresse.

$ea 2

Deuxième adresse effective de la dernière instruction exécutée. Si cette instruction n’a pas deux adresses effectives, le débogueur affiche « Erreur de registre incorrect ».

$exp

Dernière expression évaluée.

$ra

Adresse de retour actuellement sur la pile.

Cette adresse est particulièrement utile dans les commandes d’exécution. Par exemple, g @$ra continue jusqu’à ce que l’adresse de retour soit trouvée (bien que gu (Go Up) soit un moyen plus précis de « sortir » de la fonction actuelle).

$ip

Registre du pointeur d’instruction.

Processeurs x86 : Identique à eip. Processeurs itanium : Lié à iip. (Pour plus d’informations, consultez la note qui suit ce tableau.) Processeurs x64 : Identique à rip.

$eventip

Pointeur d’instruction au moment de l’événement actuel. Ce pointeur correspond généralement à $ip, sauf si vous avez changé de threads ou modifié manuellement la valeur du pointeur d’instruction.

$previp

Pointeur d’instruction au moment de l’événement précédent. (La rupture dans le débogueur compte comme un événement.)

$relip

Pointeur d’instruction lié à l’événement actuel. Lorsque vous effectuez un suivi de branche, ce pointeur est le pointeur vers la source de branche.

$scopeip

Pointeur d’instruction pour le contexte local actuel (également appelé étendue).

$exentry

Adresse du point d’entrée du premier exécutable du processus en cours.

$retreg

Registre de la valeur de retour primaire.

Processeurs x86 : Identique à eax. Processeurs itanium : Identique à ret0. Processeurs x64 : Identique à rax.

$retreg 64

Registre de valeur de retour principal, au format 64 bits.

Processeur x86 : Identique à la paire edx :eax .

$csp

Pointeur de la pile d’appels actuel. Ce pointeur est le registre le plus représentatif de la profondeur de la pile des appels.

Processeurs x86 : Identique à esp. Processeurs itanium : Identique à bsp. Processeurs x64 : Identique à rsp.

$p

Valeur imprimée par la dernière commande d* (Afficher la mémoire).

$proc

Adresse du processus actuel (autrement dit, l’adresse du bloc EPROCESS).

$thread

Adresse du thread actif. Dans le débogage en mode noyau, cette adresse est l’adresse du bloc ETHREAD. Dans le débogage en mode utilisateur, cette adresse est l’adresse du bloc d’environnement de thread (TEB).

$peb

Adresse du bloc d’environnement de processus (PEB) du processus en cours.

$teb

Adresse du bloc d’environnement de thread (TEB) du thread actif.

$tpid

ID de processus (PID) pour le processus qui possède le thread actif.

$tid

ID de thread pour le thread actif.

$dtid

$dpid

$dsid

numéro $bp

Adresse du point d’arrêt correspondant. Par exemple, $bp 3 (ou $bp 03) fait référence au point d’arrêt dont l’ID de point d’arrêt est 3. Nombre est toujours un nombre décimal. Si aucun point d’arrêt n’a un ID de Nombre, $bpNombre est évalué à zéro. Pour plus d’informations sur les points d’arrêt, consultez Utilisation de points d’arrêt.

$frame

Index de trame actuel. Cet index est le même numéro de trame que la commande .frame (Définir le contexte local) utilise.

$dbgtime

Heure actuelle, en fonction de l’ordinateur sur lequel le débogueur s’exécute.

$callret

Valeur de retour de la dernière fonction que .call (Call Function) a appelée ou qui est utilisée dans une commande .fnret /s . Le type de données de $callret est le type de données de cette valeur de retour.

$extret

$extin

$clrex

$lastclrex

Débogage managé uniquement : Adresse de l’objet d’exception CLR (Common Language Runtime) rencontré pour la dernière fois.

$ptrsize

Taille d’un pointeur. En mode noyau, cette taille est la taille du pointeur sur l’ordinateur cible.

$pagesize

Nombre d’octets dans une page de mémoire. En mode noyau, cette taille correspond à la taille de page sur l’ordinateur cible.

$pcr

$pcrb

$argreg

$exr_chance

Chance de l’enregistrement d’exception actuel.

$exr_code

Code d’exception pour l’enregistrement d’exception actuel.

$exr_numparams

Nombre de paramètres dans l’enregistrement d’exception actuel.

$exr_param0

Valeur du paramètre 0 dans l’enregistrement d’exception actuel.

$exr_param1

Valeur du paramètre 1 dans l’enregistrement d’exception actuel.

$exr_param2

Valeur du paramètre 2 dans l’enregistrement d’exception actuel.

$exr_param3

Valeur du paramètre 3 dans l’enregistrement d’exception actuel.

$exr_param4

Valeur du paramètre 4 dans l’enregistrement d’exception actuel.

$exr_param5

Valeur du paramètre 5 dans l’enregistrement d’exception actuel.

$exr_param6

Valeur du paramètre 6 dans l’enregistrement d’exception actuel.

$exr_param7

Valeur du paramètre 7 dans l’enregistrement d’exception actuel.

$exr_param8

Valeur du paramètre 8 dans l’enregistrement d’exception actuel.

$exr_param9

Valeur du paramètre 9 dans l’enregistrement d’exception actuel.

$exr_param10

Valeur du paramètre 10 dans l’enregistrement d’exception actuel.

$exr_param11

Valeur du paramètre 11 dans l’enregistrement d’exception actuel.

$exr_param12

Valeur du paramètre 12 dans l’enregistrement d’exception actuel.

$exr_param13

Valeur du paramètre 13 dans l’enregistrement d’exception actuel.

$exr_param14

Valeur du paramètre 14 dans l’enregistrement d’exception actuel.

$bug_code

Si un bogue case activée s’est produit, il s’agit du code de bogue. S’applique au débogage en mode noyau actif et aux vidages sur incident du noyau.

$bug_param1

Si un bogue case activée s’est produit, il s’agit de la valeur du paramètre 1. S’applique au débogage en mode noyau actif et aux vidages sur incident du noyau.

$bug_param2

Si un bogue case activée s’est produit, il s’agit de la valeur du paramètre 2. S’applique au débogage en mode noyau actif et aux vidages sur incident du noyau.

$bug_param3

Si un bogue case activée s’est produit, il s’agit de la valeur du paramètre 3. S’applique au débogage en mode noyau actif et aux vidages sur incident du noyau.

$bug_param4

Si un bogue case activée s’est produit, il s’agit de la valeur du paramètre 4. S’applique au débogage en mode noyau actif et aux vidages sur incident du noyau.

Certains de ces pseudo-registres peuvent ne pas être disponibles dans certains scénarios de débogage. Par exemple, vous ne pouvez pas utiliser $peb, $tid et $tpid lorsque vous déboguez un minidump en mode utilisateur ou certains fichiers de vidage en mode noyau. Dans certaines situations, vous pouvez apprendre les informations de thread à partir de ~ (État du thread), mais pas à partir de $tid. Vous ne pouvez pas utiliser le $previp pseudo-inscription sur le premier événement de débogueur. Vous ne pouvez pas utiliser le pseudo-enregistrement $relip , sauf si vous effectuez un suivi de branche. Si vous utilisez un pseudo-registre non disponible, une erreur de syntaxe se produit.

Un pseudo-registre qui contient l’adresse d’une structure (par exemple , $thread, $proc, $teb, $peb et $lastclrex ) est évalué en fonction du type de données approprié dans l’évaluateur d’expression C++, mais pas dans l’évaluateur d’expression MASM. Par exemple, la commande ? $teb affiche l’adresse du TEB, tandis que la commande ?? @$teb affiche l’ensemble de la structure TEB. Pour plus d’informations, consultez Évaluation des expressions.

Sur un processeur Itanium, le registre iip est aligné sur le bundle, ce qui signifie qu’il pointe vers l’emplacement 0 dans le bundle contenant l’instruction actuelle, même si un autre emplacement est exécuté. Iip n’est donc pas le pointeur d’instruction complet. Le pseudo-registre $ip est le pointeur d’instruction réel, y compris le bundle et l’emplacement. Les autres pseudo-registres qui contiennent des pointeurs d’adresse ($ra, $retreg, $eventip, $previp, $relip et $exentry) ont la même structure que $ip sur tous les processeurs.

Vous pouvez utiliser la commande r pour modifier la valeur de $ip. Cette modification modifie également automatiquement le registre correspondant. Lorsque l’exécution reprend, elle reprend à la nouvelle adresse du pointeur d’instruction. Ce registre est le seul pseudo-registre automatique que vous pouvez modifier manuellement.

Note Dans la syntaxe MASM, vous pouvez indiquer la $ip pseudo-inscription avec un point ( ). Vous n’ajoutez pas de signe at (@) avant cette période et n’utilisez pas le point comme premier paramètre de la commande r . Cette syntaxe n’est pas autorisée dans une expression C++.

Les pseudo-registres automatiques sont similaires aux alias automatiques. Toutefois, vous pouvez utiliser des alias automatiques avec des jetons liés aux alias (tels que ${ }), et vous ne pouvez pas utiliser de pseudo-registres avec ces jetons.

Pseudo-Registers définies par l’utilisateur

Il existe 20 pseudo-registres définis par l’utilisateur ($t 0, $t 1, ..., $t 19). Ces pseudo-registres sont des variables que vous pouvez lire et écrire via le débogueur. Vous pouvez stocker n’importe quelle valeur entière dans ces pseudo-registres. Elles peuvent être particulièrement utiles en tant que variables de boucle.

Pour écrire dans l’un de ces pseudo-registres, utilisez la commande r (Registres), comme le montre l’exemple suivant.

0:000> r $t0 = 7
0:000> r $t1 = 128*poi(MyVar)

Comme tous les pseudo-registres, vous pouvez utiliser le pseudo-registre défini par l’utilisateur dans n’importe quelle expression, comme le montre l’exemple suivant.

0:000> bp $t3 
0:000> bp @$t4 
0:000> ?? @$t1 + 4*@$t2 

Un pseudo-registre est toujours tapé en tant qu’entier, sauf si vous utilisez le commutateur ? avec la commande r . Si vous utilisez ce commutateur, le pseudo-registre acquiert le type de ce qui lui est affecté. Par exemple, la commande suivante attribue le type UNICODE_STRING** et la valeur 0x0012FFBC à $t 15.

0:000> r? $t15 = * (UNICODE_STRING*) 0x12ffbc

Les pseudo-registres définis par l’utilisateur utilisent zéro comme valeur par défaut au démarrage du débogueur.

Note Les alias $u 0, $u 1, ..., $u 9 ne sont pas des pseudo-registres, malgré leur apparence similaire. Pour plus d’informations sur ces alias, consultez Utilisation d’alias.

Exemple

L’exemple suivant définit un point d’arrêt qui est atteint chaque fois que le thread actuel appelle NtOpenFile. Toutefois, ce point d’arrêt n’est pas atteint lorsque d’autres threads appellent NtOpenFile.

kd> bp /t @$thread nt!ntopenfile

Exemple

L’exemple suivant exécute une commande jusqu’à ce que le registre contienne une valeur spécifiée. Tout d’abord, placez le code suivant pour le pas à pas conditionnel dans un fichier de script nommé « eaxstep ».

.if (@eax == 1234) { .echo 1234 } .else { t "$<eaxstep" }

Ensuite, exécutez la commande suivante.

t "$<eaxstep"

Le débogueur effectue une étape, puis exécute votre commande. Dans ce cas, le débogueur exécute le script, qui affiche 1234 ou répète le processus.