bp, bu, bm (Définir le 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.

User-Mode

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

Kernel-Mode

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

Paramètres

Fil
Spécifie le thread auquel le point d’arrêt s’applique. Pour plus d’informations sur la syntaxe, consultez Syntaxe de thread. 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 (renuméroter le 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 de points d’arrêt).

Lorsque vous utilisez 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’IDENTIFICATION . Si vous placez l’ID entre crochets ([]), l’ID peut inclure n’importe quelle expression. Pour plus d’informations sur la syntaxe, consultez Syntaxe d’expression numérique.

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

/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.

/pEProcess
(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 est déclenché uniquement s’il est rencontré dans le contexte de ce processus.

/tEThread
(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 de thread. Le point d’arrêt est déclenché uniquement s’il est rencontré dans le contexte de ce thread. Si vous utilisez /pEProcess et /tEThread, vous pouvez les entrer dans n’importe quel ordre.

/cMaxCallStackDepth
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.

/CMinCallStackDepth
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.

/Un
(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 des points 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 selon SymbolPattern. Utilisez /d pour éviter de réévaluer les 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 à laquelle le point d’arrêt est destiné.

Expression de l’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 de modèle de données (dx) qui prend la valeur true (correspond à condition – break) ou false (ne correspond pas à la condition – ne pas s’arrêter).

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 à l’aide de JavaScript.

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

Pour plus d’informations sur les objets débogueur, consultez dx (Display Debugger Object Model Expression).

Pour plus d’informations sur les points d’arrêt conditionnels, consultez Définition 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 Address, le pointeur d’instruction actuel est utilisé. Pour plus d’informations sur la syntaxe, consultez Syntaxe des adresses et des plages d’adresses.

Passe
Spécifie le numéro de la passe d’exécution sur laquelle le point d’arrêt est activé. Le débogueur ignore l’emplacement du point d’arrêt jusqu’à ce qu’il atteigne le passage spécifié. La valeur de 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 que l’application a exécuté le code au moins une fois, entrez une valeur de 2 ou plus. 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 qui est décrémenté à chaque passage dans le code. Pour afficher les valeurs initiales et actuelles du compteur Passes, utilisez bl (Liste de 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 parcourez le code ou effectuez un suivi au-delà de celui-ci. Lorsque le compteur Passes atteint 1, vous pouvez le réinitialiser uniquement en effaçant 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 de fois spécifié. 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 entre guillemets incorporé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 parcourez le code ou effectuez un suivi au-delà de ce point.

Toute commande qui reprend l’exécution du programme après un point d’arrêt (par exemple , 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 à des 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 de caractères génériques de chaîne. Étant donné que ces caractères sont mis en correspondance avec des symboles, la correspondance ne respecte pas la casse et un trait de soulignement de début unique (_) représente toute quantité de traits de soulignement de début.

Environnement

Élément Description
Modes mode utilisateur, mode noyau
Targets débogage actif uniquement
Plateformes all

Informations supplémentaires

Pour plus d’informations et des exemples sur l’utilisation des points d’arrêt, d’autres commandes et méthodes de contrôle des points d’arrêt, et sur la façon de définir 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 Définition d’un point d’arrêt conditionnel.

Remarques

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 (bu Points d’arrêt).

  • La commande bm (Set Symbol Breakpoint) 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 ne suit pas 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 une modification de module déplace le code auquel un point d’arrêt bp a été défini, le point d’arrêt reste à la même adresse. D’autre part, un point d’arrêt bu reste 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. D’autre part, 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 symbole pour un point d’arrêt. La syntaxe bm SymbolPattern équivaut à utiliser x SymbolPattern, puis à utiliser bu sur chaque résultat. Par exemple, pour définir des points d’arrêt sur tous les symboles du module Myprogram qui commencent 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 du processeur. Si un point d’arrêt logiciel est placé dans les données du 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 à cet emplacement sera utilisée en tant que code exécutable et non en tant que données de programme. Sinon, vous devez utiliser la commande ba (Interrompre l’accès) à 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, consultez 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, des 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 ~123 pb définit un point d’arrêt sur le thread 123. Les commandes ~bp et ~.bp définissent un point d’arrêt sur le thread actif.

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 (Interruption sur accès) 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 (et pas seulement le processeur 3) provoque une interruption 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 en lecture seule ou du code qui ne peut pas être modifié, utilisez une commande ba e, où e représente l’accès d’exécution seule.

La commande suivante définit un point d’arrêt de 12 octets après le début de la fonction MyTest. Ce point d’arrêt est ignoré pour les six premiers passages dans le code, mais l’exécution s’arrête au 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 lui. Les commandes .bpcmds (Display Breakpoint Commands) peuvent être utilisées pour faire la distinction entre ces deux types. Si le point d’arrêt a été créé par bm sans le commutateur /d , l’affichage .bpcmds indique le type de point d’arrêt en tant que bu, suivi du symbole évalué placé dans le jeton @ !" » (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 comme 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 ;