paint-brush
Points d'arrêt : la puissance massive qu'ils ont expliquéepar@shai.almog

Points d'arrêt : la puissance massive qu'ils ont expliquée

par Shai Almog10m2023/01/02
Read on Terminal Reader

Trop long; Pour lire

En savoir plus sur les points de trace (points de journalisation AKA) comment les points d'arrêt d'exception n'ont pas à sucer, les points de surveillance, les filtres et pourquoi les points d'arrêt de méthode sont problématiques.
featured image - Points d'arrêt : la puissance massive qu'ils ont expliquée
Shai Almog HackerNoon profile picture

Ça a été une grosse semaine. Je suis actuellement en train de réviser le brouillon final de mon prochain livre de débogage . C'est toujours un moment dégrisant et excitant. Un moment où tout d'un coup tous les mois de travail deviennent "réels".


J'ai également enregistré 9 vidéos pour youtube portant le nombre total de vidéos du cours à 29 (avec beaucoup d'autres en cours de route). Je commence deux cours gratuits supplémentaires, l'un destiné aux débutants absolus .


Un autre concerne la programmation Java moderne que je lancerai très bientôt. Les deux seront gratuits sur (obligatoire "liker, s'abonner et partager").


Dans le post de cette semaine, nous parlerons des points d'arrêt. C'est long car ce que nous entendons par point d'arrêt n'est en fait que "point d'arrêt de ligne". Il y en a beaucoup plus comme vous pouvez le voir ci-dessous.

Transcription

Bienvenue dans la quatrième partie du débogage à Scale où nous bottons des culs et prenons des noms. Noms de variables !


Dans cette section, nous discutons des points d'arrêt qui sont les unités de travail les plus élémentaires lors du débogage. Mais il y a tellement plus pour eux que de simplement casser.


Nous avons parlé du point d'arrêt le plus élémentaire dans notre premier épisode. Cette fois, nous allons creuser un peu plus et dans certaines des nuances les moins connues.

Points d'arrêt conditionnels

Nous commençons avec des points d'arrêt conditionnels. Les points d'arrêt conditionnels nous permettent de définir une condition pour un point d'arrêt atteint. Cela empêche le thread de s'arrêter constamment sur un point d'arrêt. J'en ai déjà discuté avec l'objet marqueur myThread que nous avons créé dans la vidéo précédente.


Dans ce cas, nous ne nous arrêtons que s'il est différent du thread en cours. Cela signifie que ce point d'arrêt n'atteindra que si un autre thread l'invoque. C'est un excellent moyen de détecter les problèmes liés aux threads comme les blocages ou les courses. Cette fonctionnalité mérite d'être répétée car c'est une fonctionnalité si importante.

Points d'arrêt de la méthode

Les points d'arrêt de méthode sont assez problématiques.


Pour rappel, nous pouvons placer un point d'arrêt de ligne sur n'importe quelle ligne de la méthode, et le point d'arrêt s'arrêtera là. C'est tellement omniprésent que nous l'appelons simplement un "point d'arrêt".


Nous pouvons basculer le point d'arrêt de ligne standard avec control-F8 ou alternativement sur un mac avec Command-F8 .


Les points d'arrêt de méthode s'arrêtent lorsque nous entrons dans une méthode. Vous pourriez penser que cela ne sert à rien. Pourquoi ne pas utiliser un point d'arrêt de ligne ?


Vous auriez raison. Les points d'arrêt de méthode sont beaucoup plus lents, et vous ne devriez pas les utiliser : pour cela… Il existe cependant un cas d'utilisation pour les points d'arrêt de méthode.


Notez que parce que les points d'arrêt de méthode sont si lents, ils sont généralement émulés par l'IDE. Il utilise simplement des points d'arrêt de ligne pour simuler des points d'arrêt de méthode. Ceci est généralement transparent pour nous en tant qu'utilisateurs de l'EDI, mais nous devons le savoir car, dans le passé, ce n'était pas le cas.


Vous pouvez toujours trouver des messages d'utilisateurs sur StackOverflow se plaignant de la lenteur des points d'arrêt de méthode.


Pour voir le cas d'utilisation des points d'arrêt de méthode, allons dans la fenêtre de gestion des points d'arrêt. Supposons que l'on veuille casser sur toutes les méthodes commençant par les lettres I et S dans les classes dont le nom commence par Prime.


Nous pouvons le faire en utilisant une expression comme celle-ci pour arrêter toutes ces méthodes basées sur un modèle. Cela peut sembler tiré par les cheveux mais est en fait très utile si vous avez une classe de base abstraite dont les sous-classes suivent une convention de dénomination et qu'elles ont de nombreuses méthodes associées.


Vous voulez tout suivre, et vous pouvez le faire en utilisant cette approche. Notez que vous pouvez également utiliser des points de trace ici et obtenir une journalisation très approfondie. Nous parlerons des points de trace dans quelques minutes.

Points de surveillance sur le terrain

Les points de surveillance sur le terrain ne sont pas votre point d'arrêt typique. Un point de surveillance s'arrêtera chaque fois que la valeur du champ change ou chaque fois qu'il est lu. C'est une façon remarquablement cool d'attraper un cas où un code mute une variable ou découvre comment une valeur de champ se propage dans le code.


Notez que nous pouvons régler s'il s'arrête aux opérations de lecture, aux opérations d'écriture ou aux deux à l'aide de cette boîte de dialogue. Nous pouvons également rendre le point de surveillance conditionnel comme nous le pouvons avec n'importe quel autre point d'arrêt.


C'est ce qu'on appelle un point de surveillance et non un point d'arrêt car ce n'est pas le point où le code s'arrête. Il s'arrête au point d'accès, pas sur le terrain lui-même.

Gestion des points d'arrêt

Les IDE fournissent une interface utilisateur de gestion pour tous les points d'arrêt. Nous pouvons gérer les points d'arrêt que nous avons déjà et créer de nouveaux points d'arrêt dans le menu Afficher les points d'arrêt. Je peux l'ouvrir via l'option de menu Afficher les points d'arrêt, ou je peux utiliser la combinaison de touches Shift-Control-F8 .


Notez que, sur un mac, nous devons utiliser la commande au lieu de la touche de contrôle.


Dans cette boîte de dialogue, nous pouvons désactiver, supprimer et modifier les points d'arrêt. Vous remarquerez que nous avons beaucoup d'options ici dont nous discuterons bientôt. Nous pouvons ajouter des points d'arrêt à partir d'ici. Il existe plusieurs options intéressantes, mais maintenant, je vais juste ajouter un simple point d'arrêt de champ.

Les points d'arrêt d'exception sucent (ou le font-ils ?)

Nous pouvons définir un point d'arrêt pour qu'il s'arrête lorsqu'une exception est levée. Mais c'est un peu un problème. J'ai deux options. Tout d'abord, je peux intercepter une exception spécifique par son nom. Ceci est utile si vous connaissez à l'avance l'exception qui sera levée.


Mais je ne peux pas penser à de nombreux cas où cela s'est produit, et je ne connaissais pas déjà la ligne où l'exception est levée.


Le cas d'utilisation le plus précieux consiste à attraper toutes les exceptions. La raison pour laquelle cela est utile est que parfois je ne regarde pas la console pendant le débogage. Des exceptions pourraient y être enregistrées et je pourrais les manquer entièrement.


Je pourrais redémarrer la session de débogage et manquer ces exceptions. Mais si un point d'arrêt s'arrête soudainement sur une exception, c'est difficile à manquer. Le problème est que la capture de toutes les exceptions est cassée par défaut !


Malheureusement, cela est difficile à montrer dans une simple application principale principale, j'ai donc changé la démo en une simple application de démarrage à ressort. Le contenu de l'application n'est pas important dans ce cas. Activons la capture de toute exception et voyons ce qui se passe…


Après avoir activé la capture, j'essaie de continuer, mais il atteint instantanément le point d'arrêt encore et encore et encore. Le code interroge un WebService en arrière-plan. Il manque un en-tête HTTP à ce WebService, de sorte que le code qui analyse cet en-tête échoue sur une NumberFormatException.


Nous sommes bloqués sur le code qui lève cette exception qui est valide car Java n'a pas fourni d'autre moyen d'analyser les en-têtes numériques lorsque ce code a été écrit.


Alors, que pouvons-nous faire? Cela rend effectivement l'arrêt sur n'importe quelle exception inutile pour presque toutes les applications du monde réel.


Déplaçons un peu la fenêtre, puis zoomons pour voir ce que nous faisons ici.


Nous pouvons maintenant définir un filtre de classe. Remarquez que je préfixe les deux filtres avec un caractère moins pour en faire un filtre d'exclusion. Ici, je définis un filtre pour tous les packages java et tous les packages sun. Cela signifie que chaque exception gérée dans ces packages ne sera pas interrompue.


Une fois que j'appuie sur OK, je peux appuyer sur Continuer et l'application s'exécute sans interruption sur les exceptions problématiques. D'autres exceptions fonctionneront comme d'habitude et nous feront savoir quand quelque chose se brise dans notre code !


C'est incroyable que ce ne soit pas la valeur par défaut de l'IDE. Sans cela, la fonctionnalité est pratiquement inutile.

Points de trace (points de journalisation AKA)

Les points de trace ou LogPoints sont quelques-uns des types de points d'arrêt les plus importants que nous ayons. Nous pouvons ajouter un point de trace en majuscule-cliquant sur la gouttière. Cela ouvre une boîte de dialogue de point d'arrêt familière, mais elle semble un peu différente. Tout d'abord, remarquez ceci :


L'option de suspension n'est pas cochée ; notez que nous pouvons convertir n'importe quel point d'arrêt en un point de trace en décochant la case à cocher suspendre. Par défaut, un point d'arrêt casse. Il arrête le thread en cours et le suspend afin que nous puissions inspecter tranquillement la pile d'applications et voir ce qui se passe.


Un point de trace ne suspend pas le thread en cours. L'application atteint le point d'arrêt, puis continue de s'exécuter sans s'arrêter. C'est assez révolutionnaire, comment enjambez-vous?


Eh bien, non. Au lieu de cela, nous pouvons faire plusieurs autres choses…


Nous pouvons enregistrer les mots "point d'arrêt atteint" chaque fois que nous atteignons le point d'arrêt, mais cela n'est pas très utile à moins que nous n'ayons qu'un seul point de trace et que nous voulions seulement savoir si nous avons atteint ce point. Nous pouvons imprimer une trace de pile à chaque fois que nous atteignons le point de trace, ce qui est en effet plus utile. Mais pas de beaucoup.


Il est difficile de lire beaucoup de traces dans une liste et de les suivre. Ce sur quoi je veux me concentrer, c'est autre chose.


Notez que l'évaluation et le journal contenaient déjà la valeur cnt car j'avais sélectionné la valeur cnt dans l'IDE avant de cliquer sur Maj dans la gouttière.


Nous pouvons écrire n'importe quelle expression que nous voulons imprimer ici. Je peux invoquer une méthode pour écrire des chaînes descriptives, etc. Il s'agit littéralement d'une instruction de journal standard que je peux ajouter dynamiquement au code. Notez que je peux toujours rendre ce point de trace conditionnel comme n'importe quel point d'arrêt conditionnel.


Cela signifie que je peux imprimer n'importe quelle valeur à ce stade. Comme n'importe quel bûcheron. C'est une caractéristique spectaculaire. Imaginez les points d'arrêt de méthode dont nous avons parlé plus tôt avec ces points de trace ; nous pouvons enregistrer instantanément à grande échelle. Appuyons sur OK.


Et puis exécutez ce programme ; nous pouvons voir le journal que nous avons ajouté dans le tracepoint imprimé sur la console comme si nous l'avions écrit dans le code !

Regroupement et dénomination

Le regroupement et la dénomination sont cruciaux une fois que nous avons intensifié notre débogage.


Nous pouvons nommer un point d'arrêt en utilisant la description pour indiquer sa signification sémantique. Ceci est très utile lorsque nous travaillons avec de nombreux points d'arrêt. Nous pouvons également les regrouper en fonction des fichiers, des packages, etc.


Mais ce qui est cool, c'est que nous pouvons créer des groupes personnalisés pour les points d'arrêt et désactiver les points d'arrêt dans le groupe avec une seule bascule. C'est très pratique !'


Cela nous évite d'appuyer fastidieusement sur continuer lorsque nous essayons d'atteindre un état et nous permet de gérer de nombreux points d'arrêt.


Mais la vraie valeur ici est à l'échelle. Supposons que vous ayez une session de débogage complexe avec plusieurs points de trace exécutés simultanément.


Vous pouvez regrouper la session et désactiver les points d'arrêt tout en passant à une branche différente pour déboguer autre chose. Revenez ensuite à l'endroit où vous étiez lorsque vous avez terminé.

Désactiver le point d'arrêt

Parfois, un point d'arrêt est constamment atteint et nous n'avons besoin que d'une pile spécifique.


Nous pouvons désactiver un point d'arrêt jusqu'à ce qu'un autre point d'arrêt ou une exception soit atteint, auquel cas le point d'arrêt sera activé automatiquement. Cela nous évite d'avoir à appuyer sur continuer tout le temps si nous ne voulons tester qu'une voie spécifique.


Cela fonctionne également avec les exceptions et les points d'arrêt d'exception, et nous pouvons décider du comportement après. Voulons-nous le désactiver à nouveau ou continuer comme d'habitude ?


Ceci est très utile dans le cas d'une panne qui ne passe que par un chemin spécifique. Je peux ajouter un point de trace à la première méthode. Ensuite, désactivez le point d'arrêt réel que je veux dans ce point de trace.

Filtres d'instances

Les filtres d'instance nous permettent d'accepter uniquement un point d'arrêt à partir d'une instance d'objet spécifique.

Remarquez l'instance de l'objet actuel marqué comme "ceci" dans la montre. Remarquez qu'il a le symbole arobase suivi du nombre 656.


Il s'agit de l'ID d'objet Java qui équivaut à un pointeur dans d'autres langages de programmation. Dans les filtres d'instance, nous pouvons limiter le point d'arrêt afin qu'il ne soit atteint que pour un objet spécifique.


Disons que ce point d'arrêt de ligne est souvent touché par plusieurs instances, mais je ne me soucie que des résultats d'une instance d'objet spécifique et je souhaite filtrer tout le bruit. Je peux ouvrir la boîte de dialogue des détails avancés en cliquant ici.


Je dois vérifier l'option de filtre d'instance, puis saisir l'ID d'objet de l'instance que je souhaite filtrer. Cela signifie que le point d'arrêt ne s'arrêtera pas pour les autres types d'instance. Pour appliquer ce changement, j'appuie sur terminé.


À ce stade, nous pouvons voir que le filtre d'instance s'arrête toujours au point d'arrêt attendu…

L'étape suivante consiste donc à remplacer le filtre d'instance par une autre instance d'objet. J'invente un chiffre car c'est juste pour un test.


Notez que lorsque je clique avec le bouton droit sur le point d'arrêt, j'obtiens une version personnalisée de cette boîte de dialogue car nous avons un filtre d'instance en place. C'est une fonctionnalité vraiment intéressante qui rend l'interface utilisateur beaucoup plus facile à utiliser.


Maintenant que nous avons apporté cette modification, le point d'arrêt ne se casse plus.

Filtres de classe

Les filtres de classe n'ont pas de sens pour un point d'arrêt de ligne typique. Les filtres de classe ont un sens lors de l'utilisation d'un point de surveillance de champ ou d'un point d'arrêt d'exception.


Dans ce cas, j'ai un champ public. Je filtre l'accès au champ pour ignorer tous les accès de la classe principale principale. Si une classe différente accède au champ, le point d'arrêt sera atteint.


C'est très utile, sinon, je pourrais obtenir beaucoup de coups sur le point de surveillance de la classe actuelle. Mais je veux voir d'autres cas.

Filtres d'appelants

Le filtre de l'appelant implémente un filtre basé sur la signature de la méthode d'appel. Pour l'utiliser, nous devons à nouveau aller dans le menu avancé. Il prend en charge les caractères génériques afin que je puisse limiter l'appelant pour n'autoriser que la méthode run.


Notez qu'il utilise la notation JVM pour la signature de méthode qui est un sujet assez complexe dont je parlerai plus tard. J'ai une section couvrant cela dans mon livre de débogage.


La méthode continue de s'arrêter au point d'arrêt comme prévu car, comme nous pouvons le voir ici, la méthode run est bien dans la trace de la pile. Ainsi, le filtre s'applique correctement et atteint le point d'arrêt.


Nous pouvons à nouveau personnaliser le point d'arrêt dans l'interface utilisateur d'édition rapide du filtre. Dans ce cas, j'ai changé le filtre pour rechercher une méthode appelée stop qui n'existe pas, et en effet, le point d'arrêt ne se casse plus.

Dernier mot

Cette vidéo a été longue, j'espère que vous l'avez trouvée instructive et complète. Dans la vidéo suivante, nous parlerons du débogage des flux et des collections.


Si vous avez des questions, veuillez utiliser la section des commentaires. Merci!