Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Dans la version 10.0.25310.1001 et ultérieure du moteur de débogage, la résolution des points d’arrêt ambigus est désormais prise en charge.
Les points d’arrêt ambigus permettent au débogueur de définir des points d’arrêt dans certains scénarios où une expression de point d’arrêt se résout à plusieurs emplacements. Par exemple, cela peut se produire quand :
- Surcharges multiples d’une fonction.
- Il existe plusieurs symboles qui correspondent à une expression de point d’arrêt.
- Le même nom de symbole est utilisé pour plusieurs emplacements.
- Le symbole a été intégré.
- Définition d’un point d’arrêt dans une fonction de modèle avec plusieurs instanciations dans la fenêtre source.
Lorsqu’il est activé, le débogueur définit un point d’arrêt sur chaque correspondance de symboles pour une expression de point d’arrêt donnée. Le débogueur filtre également les correspondances de symboles si certains critères sont remplis.
Pour obtenir des informations générales sur l’utilisation de points d’arrêt, consultez Utilisation de points d’arrêt.
Activation d’une résolution de point d’arrêt ambiguë
Par défaut, les points d’arrêt ambigus sont désactivés. Pour l’activer dans une session de débogueur, exécutez cette commande dans la console WinDbg :
dx @$debuggerRootNamespace.Debugger.Settings.EngineInitialization.ResolveAmbiguousBreakpoints = true;
Pour confirmer que le paramètre de points d’arrêt ambigus est actif :
0:010> dx @$debuggerRootNamespace.Debugger.Settings.EngineInitialization.ResolveAmbiguousBreakpoints
@$debuggerRootNamespace.Debugger.Settings.EngineInitialization.ResolveAmbiguousBreakpoints : true
Pour plus d’informations sur l’utilisation de la commande dx, consultez dx (Display Debugger Object Model Expression).
Pour désactiver la fonctionnalité, définissez la valeur falseci-dessus sur . Pour vous assurer que le paramètre persiste entre les sessions, veillez à cliquer File -> Settings -> Debugger Settings dessus, puis cochez la case marquée Persist engine settings across debugger sessions.
L’utilisation s’applique aux points d’arrêt uniques
La résolution des expressions de point d’arrêt ambiguës s’applique uniquement à l’exécution de la commande de point d’arrêt pour définir un point d’arrêt unique dans le débogueur. En d’autres termes, la définition de plusieurs points d’arrêt avec la bm commande continuera de fonctionner comme d’habitude. L’exécution de la commande avec cette fonctionnalité activée entraînera un nouveau comportement pour les points d’arrêt uniques.
Pour obtenir des informations générales sur les commandes de point d’arrêt, consultez bp, bu, bm (Définir le point d’arrêt).
Points d’arrêt hiérarchiques
Les points d’arrêt hiérarchiques représentent le résultat de la résolution d’une expression de point d’arrêt ambiguë en plusieurs points d’arrêt. Si une expression entraîne deux ou plusieurs correspondances à utiliser pour définir des points d’arrêt, un autre point d’arrêt est créé pour contrôler l'ensemble de points d’arrêt. Ce point d’arrêt substituant, le point d’arrêt hiérarchique, peut être activé/désactivé/effacé et répertorié comme un point d’arrêt normal, avec la fonctionnalité ajoutée d’exécution de la même opération sur les points d’arrêt qu’il possède.
Par exemple, si la commande bp foo!bar est exécutée, ce qui entraîne deux correspondances par rapport au symbole bar, un point d’arrêt hiérarchique est créé qui contrôle les deux correspondances. Si la hiérarchie est activée/désactivée/effacée, les points d'arrêt correspondants le seront également.
Les commandes .bpcmds(Display Breakpoint Commands) répertorient la commande de point d’arrêt qui peut être exécutée pour définir chaque point d’arrêt. Les points d’arrêt appartenant à un point d’arrêt hiérarchique répertorient toujours une commande bp valide qui définit un point d’arrêt sur son adresse. Les points d’arrêt hiérarchiques sont également répertoriés dans la sortie et affichent la commande qui peut être utilisée pour recréer l’ensemble des points d’arrêt au lieu d’un seul point d’arrêt.
Symboles ambigus
La définition d’un point d’arrêt sur un nom de symbole doit entraîner le comportement suivant si le symbole est :
Surcharge : chaque surcharge qui correspond au symbole doit avoir un point d’arrêt.
Fonction de modèle :
Si l’expression a tous les paramètres de modèle spécifiés (par exemple
bp foo!bar<int>), un point d’arrêt est défini sur l’implémentation spécifique de la fonction de modèle.Si l’expression n’a aucune implémentation de type spécifiée (par exemple
bp foo!bar), aucun point d’arrêt n’est défini. Dans ce cas, vous devez utiliserbmpour définir des points d'arrêt sur la fonction template.Les spécifications partielles du modèle ne sont pas prises en charge par le débogueur et aucun point d’arrêt n’est défini dans ce cas.
Fonction intégrée : chaque emplacement intégré a un point d’arrêt
Notez que plusieurs points d’arrêt ne seront pas définis lorsque l’expression de symbole inclut des opérateurs ou des décalages qui nécessitent davantage d’évaluation par le débogueur. Par exemple, si le symbole foo se résout à plusieurs emplacements, mais que l’expression foo+5 est évaluée, le débogueur ne tente pas de résoudre tous les emplacements pour les points d’arrêt à définir.
Exemples de code de point d’arrêt
Étant donné l’extrait de code suivant :
class BikeCatalog
{
public:
void GetNumberOfBikes()
{
std::cout << "There are 42 bikes." << std::endl;
}
int GetNumberOfBikes(int num)
{
std::cout << "There are " << num << " bikes." << std::endl;
return num;
}
};
L’appel de la commande bu BikeCatalog::GetNumberOfBikes entraînerait la création de deux points d’arrêt, un pour chaque surcharge. La liste des points d’arrêt entraîne la sortie suivante :
0:000> bl
2 e Disable Clear <hierarchical breakpoint> 0001 (0001) 0:**** {BikeCatalog!BikeCatalog::GetNumberOfBikes}
0 e Disable Clear 00007ff6`c6f52200 [C:\BikeCatalog\BikeCatalog.cpp @ 13] 0001 (0001) 0:**** BikeCatalog!BikeCatalog::GetNumberOfBikes
1 e Disable Clear 00007ff6`c6f522a0 [C:\BikeCatalog\BikeCatalog.cpp @ 9] 0001 (0001) 0:**** BikeCatalog!BikeCatalog::GetNumberOfBikes
Lignes sources ambiguës
La définition d’un point d’arrêt sur une ligne source doit entraîner le comportement suivant si la ligne source est :
- Fonction optimisée par le compilateur : si la ligne est fractionnée à plusieurs emplacements en raison d’optimisations du compilateur, un point d’arrêt est défini sur l’emplacement le plus bas dans la fonction correspondant à la ligne spécifiée.
- Fonction en ligne : un point d’arrêt est défini pour chacun des sites d’appel, sauf si la ligne spécifiée a été optimisée dans le cadre du processus d'inlining.
- Résolu à plusieurs emplacements : si les conditions ci-dessus ne sont pas remplies, un point d’arrêt est défini pour chaque adresse avec les conditions suivantes :
- S’il existe un ensemble d’adresses N qui correspondent à la ligne source dans l’expression et qu’un sous-ensemble de ces adresses N n’a aucun déplacement de ligne source de la ligne source dans l’expression, seules les adresses M auront des points d’arrêt.
- S’il n’existe aucune adresse dans l’ensemble d’adresses N qui ont zéro déplacement de ligne source de la ligne source dans l’expression, toutes les adresses N auront des points d’arrêt.
Filtrage basé sur l’index de symboles
Chaque symbole doit avoir un index de symbole unique. Pour plus d’informations sur la structure des symboles, consultez SYMBOL_INFO structure.
Le débogueur utilisera l'index des symboles pour s'assurer que les correspondances en double sont filtrées en cas de la présence de plusieurs adresses avec aucun déplacement de ligne de code source.
Exemples de fonctions template et surchargées
Fonctions des modèles de gestionnaire des ressources Azure
La définition d’un point d’arrêt sur la ligne source pour la définition d’une fonction de modèle entraîne un point d’arrêt pour chaque implémentation de la fonction de modèle. Étant donné la fonction de modèle suivante sur la ligne 19 de BikeCatalog.cpp:
template <class T>
void RegisterBike(T id)
{
std::cout << "Registered bike " << id << std::endl;
}
Et ses utilisations :
catalog.RegisterBike("gravel bike");
catalog.RegisterBike(1234);
L’appel de la commande bp `BikeCatalog.cpp:19` définit deux points d’arrêt correspondant aux implémentations de la fonction template qui sont utilisées plus tard dans le fichier. Si l’utilisateur souhaitait définir un point d’arrêt unique sur la fonction, il devra définir un point d’arrêt sur la ligne source spécifique de l’implémentation de la fonction de modèle ou définir un point d’arrêt sur le symbole de la fonction de modèle avec les informations de type appropriées (par exemple bp BikeCatalog::RegisterBike<int>).
La liste des points d’arrêt entraîne la sortie suivante :
0:000> bl
2 e Disable Clear <hierarchical breakpoint> 0001 (0001) 0:**** {BikeCatalog!BikeCatalog::RegisterBike<int>}
0 e Disable Clear 00007ff7`6b691dd0 [C:\BikeCatalog\BikeCatalog.cpp @ 20] 0001 (0001) 0:**** BikeCatalog!BikeCatalog::RegisterBike<int>
1 e Disable Clear 00007ff7`6b691e60 [C:\BikeCatalog\BikeCatalog.cpp @ 20] 0001 (0001) 0:**** BikeCatalog!BikeCatalog::RegisterBike<char const *>
Fonctions surchargées
La définition d’un point d’arrêt sur la ligne source pour la définition d’une fonction surchargée n’entraîne qu’un seul point d’arrêt sur cette définition de la fonction surchargée. Réutilisation de l’extrait de code ci-dessus, avec la première ligne commençant à la ligne 5 :
class BikeCatalog
{
public:
void GetNumberOfBikes()
{
std::cout << "There are 42 bikes." << std::endl;
}
int GetNumberOfBikes(int num)
{
std::cout << "There are " << num << " bikes." << std::endl;
return num;
}
};
L’appel de la commande bp `BikeCatalog.cpp:9` définit un point d’arrêt unique sur la ligne pour l’implémentation void de GetNumberOfBikes. La liste des points d’arrêt entraîne la sortie suivante :
0:000> bl
0 e Disable Clear 00007ff7`6b691ec0 [C:\BikeCatalog\BikeCatalog.cpp @ 9] 0001 (0001) 0:**** BikeCatalog!BikeCatalog::GetNumberOfBikes
Fonctions inline
La définition d’un point d’arrêt sur la ligne source pour le site d’appel d’une fonction inline n’entraîne qu’un seul point d’arrêt sur ce site d’appel particulier, même s’il existe un autre site d’appel présent dans la même fonction.
Plusieurs points d’arrêt hiérarchiques
Les points d’arrêt hiérarchiques posséderont chaque point d’arrêt dans leur ensemble, sauf si :
Un point d’arrêt dans son jeu est effacé
- Le point d’arrêt hiérarchique est effacé.
- Un autre point d’arrêt hiérarchique est créé qui inclut un point d’arrêt dans l’ensemble de ce point d’arrêt hiérarchique.
Une autre façon de penser à cela est que les points d’arrêt peuvent avoir un seul propriétaire de point d’arrêt hiérarchique et que la commande de point d’arrêt la plus récente détermine l’état de la liste des points d’arrêt.
En outre, un point d’arrêt hiérarchique ne peut pas posséder un autre point d’arrêt hiérarchique.
Incorporation de points d'arrêt préexistants
Si un point d’arrêt A existe lui-même et qu’une expression de point d’arrêt ambiguë est résolue pour créer des points d’arrêt A, B, A sera inclus dans le nouveau jeu de points d’arrêt avec B.
Intégration des intersections d'ensemble de points de rupture hiérarchiques
Si un point d’arrêt hiérarchique A possède des points d’arrêt B, C , puis une expression de point d’arrêt ambiguë est résolue pour créer des points d’arrêt :
B, C, D : Points d’arrêt B, C rejoint le nouveau groupe de points d’arrêt hiérarchique avec le point d’arrêt D et le point d’arrêt hiérarchique A sera effacé.
C, D ou B, D : l’un des points d’arrêt rejoint le nouveau groupe de points d’arrêt hiérarchiques avec le point d’arrêt D et le point d’arrêt hiérarchique A continue d’exister avec le point d’arrêt restant qui n’a pas rejoint le nouveau groupe.