Partager via


Résolution des points d’arrêt ambigus

Dans la version 10.0.25310.1001 et ultérieure du moteur de débogueur, 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 lorsque :

  • Il existe plusieurs surcharges d’une fonction.
  • Il y a 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é en ligne.
  • Définir un point d’arrêt dans une fonction modèle avec plusieurs instanciations dans la fenêtre de source.

Lorsqu’elle est activée, le débogueur définira un point d’arrêt sur chaque correspondance de symbole pour une expression de point d’arrêt donnée. Le débogueur filtrera également les correspondances de symboles si certains critères sont remplis.

Pour des informations générales sur l’utilisation des points d’arrêt, consultez la section Utilisation des points d’arrêt.

Activer la résolution des points d’arrêt ambigus

Par défaut, les points d’arrêt ambigus sont désactivés. Pour activer cette fonctionnalité 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 (Afficher l’expression du modèle d’objet de débogage).

Pour désactiver la fonctionnalité, définissez la valeur ci-dessus sur false. Pour vous assurer que le paramètre persiste entre les sessions, assurez-vous de cliquer sur File -> Settings -> Debugger Settings 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 points d’arrêt ambigus ne s’applique qu’à l’exécution de la commande de point d’arrêt pour définir un seul point d’arrêt dans le débogueur. En d’autres termes, définir plusieurs points d’arrêt avec la commande bm continuera à fonctionner comme d’habitude. Exécuter la commande avec cette fonctionnalité activée entraînera un nouveau comportement des points d’arrêt pour les points d’arrêt uniques.

Pour des informations générales sur les commandes de point d’arrêt, consultez la section 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 donne lieu à deux correspondances ou plus qui seront utilisées pour définir des points d’arrêt, un autre point d’arrêt est créé pour contrôler l’ensemble des points d’arrêt. Ce point d’arrêt de remplacement, le point d’arrêt hiérarchique, peut être activé/désactivé/supprimé et répertorié comme un point d’arrêt normal, avec la fonctionnalité supplémentaire d’effectuer 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, entraînant deux correspondances contre le symbole bar, alors un point d’arrêt hiérarchique sera créé pour contrôler les deux correspondances. Si le hiérarchique est activé/désactivé/supprimé, les points d’arrêt correspondants le seront aussi.

La commande .bpcmds(Display Breakpoint Commands) affichera 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 afficheront toujours une commande bp valide qui définira un point d’arrêt à son adresse. Les points d’arrêt hiérarchiques seront également répertoriés dans la sortie et afficheront la commande qui peut être utilisée pour recréer l’ensemble des points d’arrêt plutôt qu’un seul point d’arrêt.

Symboles ambigus

Définir un point d’arrêt sur un nom de symbole devrait entraîner le comportement suivant si le symbole est :

  • Une surcharge : Chaque surcharge correspondant au symbole doit avoir un point d’arrêt.

  • Une fonction modèle :

    • Si l’expression a tous les paramètres de modèle spécifiés (par exemple bp foo!bar<int>), alors un point d’arrêt sera défini sur l’implémentation spécifique de la fonction modèle.

    • Si l’expression n’a aucun type d’implémentation spécifié (par exemple bp foo!bar), alors aucun point d’arrêt ne sera défini. Dans ce cas, bm devrait être utilisé pour définir des points d’arrêt sur la fonction modèle.

    • Les spécifications partielles de modèles ne sont pas prises en charge par le débogueur et aucun point d’arrêt ne sera défini dans ce cas.

  • Une fonction en ligne : Chaque emplacement en ligne 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 nécessitant une évaluation supplémentaire 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 n’essaiera pas de résoudre tous les emplacements pour définir des points d’arrêt.

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’invocation 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 donnerait 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 source ambiguës

Définir un point d’arrêt sur une ligne source devrait entraîner le comportement suivant si la ligne source est :

  • Une fonction optimisée par le compilateur : Si la ligne est divisée en plusieurs emplacements en raison des optimisations du compilateur, alors un point d’arrêt sera défini sur l’emplacement le plus bas dans la fonction correspondant à la ligne spécifiée.
  • Une fonction en ligne : Un point d’arrêt est défini pour chaque site d’appel, sauf si la ligne spécifiée a été optimisée dans le cadre de l’inlining.
  • Résolu à plusieurs emplacements : Si les conditions ci-dessus ne sont pas remplies, alors un point d’arrêt sera défini pour chaque adresse avec les conditions suivantes :
    • S’il y a un ensemble de N adresses correspondant à la ligne source dans l’expression, et qu’un sous-ensemble M de ces N adresses n’a aucun déplacement de ligne source par rapport à la ligne source dans l’expression, alors seules les adresses M auront des points d’arrêt.
    • S’il n’y a pas d’adresses dans l’ensemble de N adresses qui n’ont aucun déplacement de ligne source par rapport à la ligne source dans l’expression, alors toutes les adresses N auront des points d’arrêt.

Filtrage basé sur l’index du symbole

Chaque symbole doit avoir un index de symbole unique. Pour des informations détaillées sur la structure des symboles, consultez structure SYMBOL_INFO.

Le débogueur utilisera l’index du symbole pour s’assurer que les correspondances en double sont filtrées en cas de plusieurs adresses avec déplacement de ligne source nul.

Exemples de fonctions modèles et surchargées

Fonctions des modèles de gestionnaire des ressources Azure

Définir un point d’arrêt sur la ligne source de la définition d’une fonction modèle entraînera un point d’arrêt pour chaque implémentation de la fonction modèle. Étant donné la fonction modèle suivante à 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’invocation de la commande bp `BikeCatalog.cpp:19` définira deux points d’arrêt qui se résolvent aux implémentations de la fonction modèle utilisées plus tard dans le fichier. Si l’utilisateur souhaitait plutôt définir un seul point d’arrêt sur la fonction, il devrait soit définir un point d’arrêt sur la ligne source spécifique de l’implémentation de la fonction modèle, soit définir un point d’arrêt sur le symbole de la fonction modèle avec les informations de type appropriées (par exemple bp BikeCatalog::RegisterBike<int>).

La liste des points d’arrêt donne la sortie suivante :

0:000> bl
     2 e Disable Clear  <hierarchical breakpoint>     0001 (0001)  0:**** {BikeCatalog!BikeCatalog::RegisterBike&lt;int&gt;}
         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

Définir un point d’arrêt sur la ligne source de la définition d’une fonction surchargée entraînera uniquement un point d’arrêt sur cette définition de la fonction surchargée. En réutilisant 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’invocation de la commande bp `BikeCatalog.cpp:9` définira un seul point d’arrêt sur la ligne pour l’implémentation void de GetNumberOfBikes. La liste des points d’arrêt donne la sortie suivante :

0:000> bl
     0 e Disable Clear  00007ff7`6b691ec0  [C:\BikeCatalog\BikeCatalog.cpp @ 9]     0001 (0001)  0:**** BikeCatalog!BikeCatalog::GetNumberOfBikes

fonctions en ligne

Définir un point d’arrêt sur la ligne source du site d’appel d’une fonction en ligne entraînera uniquement un point d’arrêt sur ce site d’appel particulier, même s’il y a un autre site d’appel présent dans la même fonction.

Points d’arrêt hiérarchiques multiples

Les points d’arrêt hiérarchiques posséderont chaque point d’arrêt dans leur ensemble sauf si :

Un point d’arrêt de son ensemble est supprimé

  • Le point d’arrêt hiérarchique est supprimé.
  • Un autre point d’arrêt hiérarchique est créé qui inclut un point d’arrêt dans cet ensemble de points d’arrêt hiérarchiques.

Une autre façon de penser cela est que les points d’arrêt ne peuvent avoir qu’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éterminera 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.

Subsomption des points d’arrêt préexistants

Si un point d’arrêt A existe par lui-même et qu’une expression de point d’arrêt ambiguë est ensuite résolue pour créer des points d’arrêt A, B, alors A sera inclus dans le nouvel ensemble de points d’arrêt avec B.

Subsomption des intersections d’ensembles de points d’arrêt hiérarchiques

Si un point d’arrêt hiérarchique A possède des points d’arrêt B, C et qu’une expression de point d’arrêt ambiguë est résolue pour créer des points d’arrêt :

  • B, C, D : Les points d’arrêt B, C rejoindront 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 sera supprimé.

  • C, D ou B, D: l’un des points d’arrêt rejoindra 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 continuera d’exister avec le point d’arrêt restant qui n’a pas rejoint le nouveau groupe.

Voir aussi

Utilisation des points d’arrêt

Syntaxe des points d’arrêt

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

Points d’arrêt non résolus (points d’arrêt bu)