Partager via


bp, bu, bm (Définir un point d’arrêt)

Les commandes bp, bu et bm définissent un ou plusieurs points d’arrêt logiciels. Vous pouvez combiner des emplacements, des conditions et des options pour définir différents types de points d’arrêt logiciels.

Mode Utilisateur

[~Thread] bp[ID] [Options] [Address [Passes]] ["CommandString"] 
[~Thread] bu[ID] [Options] [Address [Passes]] ["CommandString"] 
[~Thread] bm [Options] SymbolPattern [Passes] ["CommandString"]

Mode Noyau

bp[ID] [Options] [Address [Passes]] ["CommandString"] 
bu[ID] [Options] [Address [Passes]] ["CommandString"] 
bm [Options] SymbolPattern [Passes] ["CommandString"]

Paramètres

Fil
Spécifie le fil d’exécution auquel le point d’arrêt s’applique. Pour plus d’informations sur la syntaxe, veuillez consulter la section Syntaxe des threads. Vous pouvez spécifier des threads uniquement en mode utilisateur. Si vous ne spécifiez pas de thread, le point d’arrêt s’applique à tous les threads.

ID
Spécifie un nombre décimal qui identifie un point d’arrêt.

Le débogueur affecte l’ID lorsqu’il crée le point d’arrêt, mais vous pouvez le modifier à l’aide de la commande br (Renumber du point d’arrêt). Vous pouvez utiliser l’ID pour faire référence au point d’arrêt dans les commandes de débogueur ultérieures. Pour afficher l’ID d’un point d’arrêt, utilisez la commande bl (Liste des points d’arrêt).

Lorsque vous utilisez l’ID dans une commande, ne tapez pas d’espace entre la commande (bp ou bu) et le numéro d’ID.

Le paramètre ID est toujours facultatif. Si vous ne spécifiez pas d’ID, le débogueur utilise le premier numéro de point d’arrêt disponible. En mode noyau, vous ne pouvez définir que 32 points d’arrêt. En mode utilisateur, vous pouvez définir n’importe quel nombre de points d’arrêt. Dans les deux cas, il n’existe aucune restriction sur la valeur du numéro d’ID . Si vous placez l’ID entre crochets ([]), l’ID peut inclure n’importe quelle expression. Pour plus d’informations sur la syntaxe, consultez la syntaxe d’expression numérique.

Options Spécifie les options de point d’arrêt. Vous pouvez spécifier n’importe quel nombre des options suivantes, sauf indication :

/1
Crée un point d’arrêt « one-shot ». Une fois ce point d’arrêt déclenché, il est supprimé de la liste des points d’arrêt.

/p EProcess
(Mode noyau uniquement) Spécifie un processus associé à ce point d’arrêt. EProcess doit être l’adresse réelle de la structure EPROCESS, et non le PID. Le point d’arrêt n’est déclenché que s’il est rencontré dans le contexte de ce processus.

/t EThread
(Mode noyau uniquement) Spécifie un thread associé à ce point d’arrêt. EThread doit être l’adresse réelle de la structure ETHREAD, et non l’ID du thread. Le point d’arrêt n’est déclenché que s’il est rencontré dans le contexte de ce thread. Si vous utilisez /p EProcess et /t EThread, vous pouvez les entrer dans n’importe quel ordre.

/c MaxCallStackDepth
Active le point d’arrêt uniquement lorsque la profondeur de la pile des appels est inférieure à MaxCallStackDepth. Vous ne pouvez pas utiliser cette option avec /C.

/C MinCallStackDepth
Active le point d’arrêt uniquement lorsque la profondeur de la pile des appels est supérieure à MinCallStackDepth. Vous ne pouvez pas utiliser cette option avec /c.

/a
(Pour bm uniquement) Définit des points d’arrêt sur tous les emplacements spécifiés, qu’ils se trouvent dans l’espace de données ou l’espace de code. Étant donné que les points d’arrêt sur les données peuvent entraîner des échecs de programme, utilisez cette option uniquement sur les emplacements connus pour être sécurisés.

/d
(Pour bm uniquement) Convertit les emplacements de point d’arrêt en adresses. Par conséquent, si le code est déplacé, les points d’arrêt restent à la même adresse, au lieu d’être définis en fonction de SymbolPattern. Utilisez /d pour éviter la réévaluation des modifications apportées aux points d’arrêt lorsque les modules sont chargés ou déchargés.

/(
(Pour bm uniquement) Inclut des informations de liste de paramètres dans la chaîne de symboles définie par SymbolString .

Cette fonctionnalité vous permet de définir des points d’arrêt sur des fonctions surchargées qui ont le même nom, mais des listes de paramètres différentes. Par exemple, bm /( myFunc définit des points d’arrêt sur myFunc(int a) et myFunc(char a). Sans « /(« , un point d’arrêt défini sur myFunc échoue, car il n’indique pas la fonction myFunc pour laquelle le point d’arrêt est destiné.

Expression d’objet /w dx Définit un point d’arrêt conditionnel basé sur la valeur booléenne retournée par l’expression d’objet dx. L’argument est une expression du modèle de données (dx) qui évalue à vrai (condition correspondante – interruption) ou à faux (condition non correspondante – pas d’interruption).

Cet exemple montre comment définir un point d’arrêt conditionnel basé sur la valeur de localVariable.

bp /w "localVariable == 4" mymodule!myfunction

Cet exemple montre comment définir un point d’arrêt en utilisant JavaScript.

bp /w "@$scriptContents.myFunc(localVariable)" @rip

Pour plus d’informations sur les objets de débogage, consultez dx (Afficher l’Expression du Modèle d’Objet de Débogage).

Pour plus d’informations sur les points d’arrêt conditionnels, consultez la mise en place d’un point d’arrêt conditionnel.

Adresse
Spécifie le premier octet de l’instruction où le point d’arrêt est défini. Si vous omettez l’adresse, le pointeur d’instruction actuel est utilisé. Pour plus d’informations sur la syntaxe, consultez la syntaxe d’adresse et de plage d’adresses.

Passe
Spécifie le nombre de transmissions d’exécution activées par le point d’arrêt. Le débogueur ignore l’emplacement du point d’arrêt jusqu’à ce qu’il atteigne la passe spécifiée. La valeur des passes peut être n’importe quelle valeur 16 bits ou 32 bits.

Par défaut, le point d’arrêt est actif la première fois que l’application exécute le code qui contient l’emplacement du point d’arrêt. Cette situation par défaut équivaut à une valeur de 1 pour les passes. Pour activer le point d’arrêt uniquement après l’exécution du code au moins une fois, entrez une valeur de 2 ou plusieurs. Par exemple, la valeur 2 active le point d’arrêt la deuxième fois que le code est exécuté.

Ce paramètre crée un compteur décrémenté sur chaque passage du code. Pour afficher les valeurs initiales et actuelles du compteur Passe, utilisez bl (Liste des points d’arrêt).

Le compteur Passes est décrémenté uniquement lorsque l’application s’exécute au-delà du point d’arrêt en réponse à une commande g (Go). Le compteur n’est pas décrémenté si vous effectuez un pas à pas dans le code ou que vous le tracez au-delà. Lorsque le compteur Passe atteint 1, vous pouvez le réinitialiser uniquement en désactivant et en réinitialisant le point d’arrêt.

CommandString
Spécifie une liste de commandes exécutées chaque fois que le point d’arrêt est rencontré le nombre spécifié de fois. Vous devez placer le paramètre CommandString entre guillemets. Utilisez des points-virgules pour séparer plusieurs commandes.

Les commandes de débogueur dans CommandString peuvent inclure des paramètres. Vous pouvez utiliser des caractères de contrôle C standard (tels que \n et \"). Les points-virgules contenus dans des guillemets de deuxième niveau (\") sont interprétés comme faisant partie de la chaîne de caractères intégrée.

Les commandes CommandString sont exécutées uniquement si le point d’arrêt est atteint pendant que l’application s’exécute en réponse à une commande g (Go). Les commandes ne sont pas exécutées si vous effectuez un pas à pas dans le code ou que vous effectuez le suivi au-delà de ce point.

Toute commande qui reprend l’exécution du programme après un point d’arrêt (tel que g ou t) met fin à l’exécution de la liste de commandes.

SymbolPattern
Spécifie un modèle. Le débogueur tente de faire correspondre ce modèle aux symboles existants et de définir des points d’arrêt sur toutes les correspondances de modèle. SymbolPattern peut contenir divers caractères génériques et spécificateurs. Pour plus d’informations sur cette syntaxe, consultez Syntaxe générique de chaîne. Étant donné que ces caractères sont mis en correspondance avec des symboles, la correspondance n’est pas sensible à la casse, et un trait de soulignement unique (_) représente toute quantité de traits de soulignement de début.

Environnement

Élément Description
Modes mode utilisateur, mode noyau
Targets uniquement en débogage
Platforms all

Informations supplémentaires

Pour plus d’informations sur les points d’arrêt et des exemples d’utilisation de points d’arrêt, d’autres commandes et méthodes de contrôle des points d’arrêt et sur la définition des points d’arrêt dans l’espace utilisateur à partir d’un débogueur de noyau, consultez Utilisation de points d’arrêt. Pour plus d’informations sur les points d’arrêt conditionnels, consultez la mise en place d’un point d’arrêt conditionnel.

Notes

Les commandes bp, bu et bm définissent de nouveaux points d’arrêt, mais elles ont des caractéristiques différentes :

  • La commande bp (Définir le point d’arrêt) définit un nouveau point d’arrêt à l’adresse de l’emplacement du point d’arrêt spécifié dans la commande. Si le débogueur ne peut pas résoudre l’expression d’adresse de l’emplacement du point d’arrêt lorsque le point d’arrêt est défini, le point d’arrêt bp est automatiquement converti en point d’arrêt bu . Utilisez une commande bp pour créer un point d’arrêt qui n’est plus actif si le module est déchargé.

  • La commande bu (Définir le point d’arrêt non résolu) définit un point d’arrêt différé ou non résolu . Un point d’arrêt bu est défini sur une référence symbolique à l’emplacement du point d’arrêt spécifié dans la commande (et non sur une adresse) et est activé chaque fois que le module avec la référence est résolu. Pour plus d’informations sur ces points d’arrêt, consultez Points d’arrêt non résolus (points d’arrêt bu).

  • La commande bm (Définir le point d’arrêt du symbole) définit un nouveau point d’arrêt sur les symboles qui correspondent à un modèle spécifié. Cette commande peut créer plusieurs points d’arrêt. Par défaut, une fois le modèle mis en correspondance, les points d’arrêt bm sont identiques aux points d’arrêt bu . Autrement dit, les points d’arrêt bm sont des points d’arrêt différés définis sur une référence symbolique. Toutefois, une commande bm /d crée un ou plusieurs points d’arrêt bp . Chaque point d’arrêt est défini sur l’adresse d’un emplacement correspondant et n’effectue pas le suivi de l’état du module.

Si vous ne savez pas quelle commande a été utilisée pour définir un point d’arrêt existant, utilisez .bpcmds (Display Breakpoint Commands) pour répertorier tous les points d’arrêt ainsi que les commandes utilisées pour les créer.

Il existe trois principales différences entre les points d’arrêt bp et les points d’arrêt bu :

  • Un emplacement de point d’arrêt bp est toujours converti en adresse. Si un changement de module déplace le code sur lequel un point d’arrêt bp a été défini, le point d’arrêt demeure à la même adresse. En revanche, un point d’arrêt bu demeure associé à la valeur symbolique (généralement un symbole plus un décalage) qui a été utilisé, et il suit cet emplacement symbolique même si son adresse change.

  • Si une adresse de point d’arrêt bp est trouvée dans un module chargé et si ce module est déchargé ultérieurement, le point d’arrêt est supprimé de la liste des points d’arrêt. En revanche, les points d’arrêt bu persistent après des déchargements et des chargements répétés.

  • Les points d’arrêt que vous définissez avec bp ne sont pas enregistrés dans les espaces de travail WinDbg. Les points d’arrêt définis avec bu sont enregistrés dans les espaces de travail.

La commande bm est utile lorsque vous souhaitez utiliser des caractères génériques dans le modèle de symboles pour un point d’arrêt. La syntaxe bm SymbolPattern est équivalente à l’utilisation de x SymbolPattern, puis à l’aide de bu sur chaque résultat. Par exemple, pour définir des points d’arrêt sur tous les symboles du module Myprogram commençant par la chaîne « mem », utilisez la commande suivante.

Exemple

0:000> bm myprogram!mem* 
  4: 0040d070 MyProgram!memcpy
 5: 0040c560 MyProgram!memmove
  6: 00408960 MyProgram!memset

Étant donné que la commande bm définit des points d’arrêt logiciels (et non des points d’arrêt du processeur), elle exclut automatiquement l’emplacement des données lorsqu’elle définit des points d’arrêt pour éviter d’endommager les données.

Il est possible de spécifier une adresse de données plutôt qu’une adresse de programme lors de l’utilisation des commandes bp ou bm/a. Toutefois, même si un emplacement de données est spécifié, ces commandes créent des points d’arrêt logiciels, et non des points d’arrêt processeur. Si un point d’arrêt logiciel est placé dans des données de programme au lieu du code exécutable, cela peut entraîner une altération des données. Par conséquent, vous devez utiliser ces commandes dans un emplacement de données uniquement si vous êtes certain que la mémoire stockée dans cet emplacement sera utilisée comme code exécutable et non comme données de programme. Sinon, vous devez utiliser la commande ba (Break on Access) à la place. Pour plus d’informations, consultez Points d’arrêt du processeur (ba Points d’arrêt).

Pour plus d’informations sur la définition d’un point d’arrêt sur un emplacement spécifié par une syntaxe plus complexe, telle qu’un membre d’une classe publique C++, ou une chaîne de texte arbitraire contenant des caractères autrement restreints, voir Syntaxe du point d’arrêt.

Si une seule ligne source logique s’étend sur plusieurs lignes physiques, le point d’arrêt est défini sur la dernière ligne physique de l’instruction ou de l’appel. Si le débogueur ne peut pas définir un point d’arrêt à la position demandée, il place le point d’arrêt à la position autorisée suivante.

Si vous spécifiez Thread, les points d’arrêt sont définis sur les threads spécifiés. Par exemple, la commande ~*bp définit des points d’arrêt sur tous les threads, ~#bp définit un point d’arrêt sur le thread qui provoque l’exception actuelle et ~123bits/s définit un point d’arrêt sur le thread 123. Les commandes ~bp et ~.bp définissent tous deux un point d’arrêt sur le thread actuel.

Lorsque vous déboguez un système multiprocesseur en mode noyau, les points d’arrêt que vous définissez à l’aide de bp ou ba (Break on Access) s’appliquent à tous les processeurs. Par exemple, si le processeur actuel est 3 et que vous tapez bp MemoryAddress pour placer un point d’arrêt sur MemoryAddress. Tout processeur qui s’exécute à cette adresse (pas seulement le processeur 3) provoque un piège de point d’arrêt.

Les commandes bp, bu et bm définissent des points d’arrêt logiciels en remplaçant l’instruction du processeur par une instruction d’arrêt. Pour déboguer du code ou du code en lecture seule qui ne peut pas être modifié, utilisez une commande ba e, où e représente l’accès en lecture seule.

La commande suivante définit un point d’arrêt de 12 octets au-delà du début de la fonction MyTest. Ce point d’arrêt est ignoré pour les six premiers passe par le code, mais l’exécution s’arrête sur le septième passage du code.

0:000> bp MyTest+0xb 7 

La commande suivante définit un point d’arrêt sur RtlRaiseException, affiche le registre eax , affiche la valeur du symbole MyVar et continue.

kd> bp ntdll!RtlRaiseException "r eax; dt MyVar; g"

Les deux commandes bm suivantes définissent trois points d’arrêt. Lorsque les commandes sont exécutées, le résultat affiché ne fait pas la distinction entre les points d’arrêt créés avec le commutateur /d et ceux créés sans celui-ci. Les commandes .bpcmds (Commandes de point d’arrêt d’affichage) peuvent être utilisées pour faire la distinction entre ces deux types. Si le point d’arrêt a été créé par bm sans commutateur /d, l’affichage .bpcmds indique le type de point d’arrêt en tant que bu, suivi du symbole évalué placé entre le jeton @ !" (ce qui indique qu’il s’agit d’un symbole littéral et non d’une expression numérique ou d’un registre). Si le point d’arrêt a été créé par bm avec le commutateur /d, l’affichage .bpcmds indique le type de point d’arrêt en tant que bp.

0:000> bm myprog!openf* 
  0: 00421200 @!"myprog!openFile"
  1: 00427800 @!"myprog!openFilter"

0:000> bm /d myprog!closef* 
  2: 00421600 @!"myprog!closeFile"

0:000> .bpcmds
bu0 @!"myprog!openFile";
bu1 @!"myprog!openFilter";
bp2 0x00421600 ;