Changement de contextes
Lors du débogage en mode noyau, de nombreux processus, threads et parfois sessions utilisateur s’exécutent en même temps. Par conséquent, les expressions telles que « adresse virtuelle 0x80002000 » ou le « registre eax » sont ambiguës. Vous devez spécifier le contexte dans lequel ces expressions peuvent être comprises.
Le débogueur comporte cinq contextes que vous pouvez définir pendant le débogage :
Le contexte de session indique la session utilisateur par défaut.
Le contexte de processus détermine la façon dont le débogueur interprète les adresses virtuelles.
Le contexte d’adresse en mode utilisateur n’est presque jamais défini directement. Il est automatiquement défini lorsque vous modifiez le contexte du processus.
Le contexte de registre détermine la façon dont le débogueur interprète les registres et contrôle également les résultats d’une trace de pile. Ce contexte est également appelé contexte de thread, bien que ce terme ne soit pas tout à fait exact. Un contexte explicite est également un type de contexte de registre. Si vous spécifiez un contexte explicite, ce dernier est utilisé au lieu du contexte de registre actuel.
Le contexte local détermine la façon dont le débogueur interprète les variables locales. Ce contexte est également appelé étendue.
Context de session
Plusieurs sessions d’ouverture de session peuvent s’exécuter en même temps. Chaque session d’ouverture de session a ses propres processus.
L’extension !session affiche toutes les sessions d’ouverture de session ou modifie le contexte de session actuel.
Le contexte de session est utilisé par les extension !sprocess et !spoolused lorsque le numéro de session saisi est « -2 ».
Lorsque le contexte de session est modifié, le contexte de processus est automatiquement remplacé par le processus actif de cette session.
Contexte de processus
Chaque processus possède son propre répertoire de pages qui enregistre la façon dont les adresses virtuelles sont mappées aux adresses physiques. Lors de l’exécution d’un thread au sein d’un processus, le système d’exploitation Windows utilise ce répertoire de pages pour interpréter les adresses virtuelles.
Pendant le débogage en mode utilisateur, le processus en cours détermine le contexte de processus. Les adresses virtuelles utilisées dans les commandes du débogueur, les extensions et les fenêtres d’information sur le débogage sont interprétées au moyen du répertoire de pages du processus en cours.
Pendant le débogage en mode noyau, vous pouvez définir le contexte de processus à l’aide de la commande .process (Définir le contexte de processus). Utilisez cette commande pour sélectionner le répertoire de pages du processus utilisé pour interpréter les adresses virtuelles. Après avoir défini le contexte de processus, vous pouvez l’utiliser dans n’importe quelle commande qui accepte des adresses. Vous pouvez même définir des points d’arrêt à cette adresse. L’inclusion d’une option /i dans la commande .process pour spécifier le débogage invasif vous permet d’utiliser le débogueur du noyau pour définir des points d’arrêt dans l’espace utilisateur.
Vous pouvez aussi définir des points d’arrêt en mode utilisateur à partir du débogueur du noyau à l’aide d’un point d’arrêt spécifique au processus sur une fonction de l’espace noyau. Définissez des points d’arrêt stratégiques et attendez que le contexte approprié se présente.
Le contexte d’adresse en mode utilisateur fait partie du contexte de processus. En règle générale, vous n’avez pas besoin de définir directement le contexte d’adresse en mode utilisateur. Si vous définissez le contexte de processus, le contexte d’adresse en mode utilisateur passe automatiquement à la base de répertoire de la table de pages pertinente pour le processus.
Lorsque vous définissez le contexte de processus pendant le débogage en mode noyau, il est conservé jusqu’à ce qu’une autre commande .process modifie le contexte. Le contexte d’adresse en mode utilisateur est également conservé jusqu’à ce qu’une commande .process ou .context le modifie. Ces contextes ne sont pas modifiés lorsque l’ordinateur cible s’exécute, et ils ne sont pas affectés par les modifications apportées au contexte de registre ou au contexte local.
Contexte de registre
Chaque thread a ses propres valeurs de registre. Ces dernières sont stockées dans les registres du processeur lorsque le thread est en cours d’exécution et en mémoire quand un autre thread s’exécute.
Pendant le débogage en mode utilisateur, le thread en cours détermine généralement le contexte de registre. Toute référence aux registres dans les commandes du débogueur, les extensions et les fenêtres d’informations de débogage est interprétée en fonction des registres du thread en cours.
Vous pouvez changer le contexte de registre pour une valeur différente de celle du thread en cours lorsque vous effectuez un débogage en mode utilisateur à l’aide de l’une des commandes suivantes :
.cxr (Afficher l’enregistrement du contexte)
.ecxr (Afficher l’enregistrement de contexte d’exception)
Pendant le débogage en mode noyau, vous pouvez contrôler le contexte de registre à l’aide de diverses commandes du débogueur, notamment les suivantes :
.thread (Définir le contexte de registre)
.cxr (Afficher l’enregistrement du contexte)
.trap (Afficher le trap frame)
Ces commandes ne modifient pas les valeurs des registres du processeur. Au lieu de cela, le débogueur récupère le contexte de registre spécifié à partir de son emplacement en mémoire. En fait, le débogueur peut récupérer uniquement les valeurs de registre enregistrées. (Les autres valeurs sont définies dynamiquement et ne sont pas enregistrées. Les valeurs enregistrées sont suffisantes pour recréer une trace de pile.
Une fois le contexte de registre défini, le nouveau contexte de registre est utilisé pour toutes les commandes qui utilisent des valeurs de registre, notamment k (Afficher la trace de la pile arrière) et r (Registers).
Cependant, lorsque vous déboguez des ordinateurs multiprocesseurs, certaines commandes vous permettent de spécifier un processeur. (Pour en savoir plus sur ces commandes, consultez Syntaxe multiprocesseur). Si vous spécifiez un processeur pour une commande, cette dernière utilise le contexte de registre du thread actif sur le processeur spécifié au lieu du contexte de registre actuel, même si le processeur spécifié est le processeur actif.
En outre, si le contexte de registre ne correspond pas au paramètre du mode processeur actuel, ces commandes produisent une sortie incorrecte ou sans signification. Pour éviter les erreurs de sortie, les commandes qui dépendent de l’état du registre échouent jusqu’à ce que vous changez le mode processeur pour qu’il corresponde au contexte de registre. Pour modifier le mode processeur, utilisez la commande .effmach (Ordinateur efficace),
La modification du contexte de registre peut également modifier le contexte local. Ainsi, le contexte de registre peut affecter l’affichage des variables locales.
En cas d’exécution d’une application, d’un pas à pas ou d’un traçage, le contexte de registre est immédiatement réinitialisé pour correspondre à la position du compteur de programme. En mode utilisateur, le contexte de registre est également réinitialisé si le processus ou le thread en cours est modifié.
Le contexte de registre affecte les traces de pile, car ces dernières commencent à l’emplacement vers lequel pointe le pointeur de pile (esp sur un processeur x86). Si le contexte de registre est défini sur une valeur non valide ou inaccessible, on ne peut pas obtenir les traces de pile.
Vous pouvez appliquer un point d’arrêt processeur (point d’arrêt de données) à un contexte de registre spécifique à l’aide de la commande .apply_dbp (Appliquer un point d’arrêt de données au contexte).
Contexte local
Lorsqu’un programme est en cours d’exécution, la signification des variables locales dépend de l’emplacement du compteur du programme, car la portée de ces dernières ne s’étend qu’à la fonction dans laquelle elles sont définies.
Lorsque vous effectuez un débogage en mode utilisateur ou en mode noyau, le débogueur utilise l’étendue de la fonction en cours (le frame actuel sur la pile) comme contexte local. Pour modifier ce contexte, utilisez la commande .frame (Définir le contexte local) ou cliquez deux fois sur le frame souhaité dans la fenêtre Appels.
Dans le débogage en mode utilisateur, le contexte local est toujours un frame dans la trace de pile du thread en cours. Dans le débogage en mode noyau, le contexte local est toujours un frame dans la trace de pile du thread du contexte de registre en cours.
Vous ne pouvez utiliser qu’un seul frame de pile à la fois pour le contexte local. Les variables locales dans d’autres frames ne sont pas accessibles.
Le contexte local est réinitialisé si l’un des événements suivants survient :
Toute exécution de programme, pas à pas ou suivi
Toute utilisation du délimiteur de thread (~) dans n’importe quelle commande
Toute modification apportée au contexte de registre
L’extension !for_each_frame vous permet d’exécuter une seule commande à plusieurs reprises, une fois pour chaque frame de la pile. Cette commande modifie le contexte local de chaque frame, exécute la commande spécifiée et retourne le contexte local à sa valeur d’origine.