Astuces de débogage IntelliJ
1. Vue d'ensemble
Dans ce didacticiel, nous examinerons quelquesadvanced IntelliJ debugging facilities.
Il est supposé que les bases du débogage sont déjà connues (comment démarrer le débogage,Step Into, actionsStep Over, etc.). Sinon, veuillez vous référer àthis article pour plus de détails à ce sujet.
2. Smart Step Into
Il existe des situations où plusieurs méthodes sont appelées sur une seule ligne de code source, commedoJob(getArg1(), getArg2()). Si nous appelons l'actionStep Into (F7), le débogueur entre dans les méthodes dans l'ordre utilisé par la JVM pour l'évaluation:getArg1 -getArg2 -doJob.
Cependant,we might want to skip all intermediate invocations and proceed to the target method directly. L'actionSmart Step Into permet de faire cela.
C'estbound to the Shift + F7 by default et ressemble à ceci lorsqu'il est appelé:
Nous pouvons maintenant choisir la méthode cible pour continuer. Notez également qu'IntelliJ place toujours la méthode la plus externe en tête de liste. Cela signifie que nous pouvons y accéder rapidement en appuyant surShift + F7 | Enter.
3. Châssis de baisse
Nous pouvons réaliser que certains traitements qui nous intéressent ont déjà eu lieu (par exemple calcul de l'argument de la méthode actuelle). Dans ce cas,it’s possible to drop the current JVM stack frame(s) in order to re-process them.
Considérez la situation suivante:
Supposons que nous soyons intéressés par le débogage du traitement degetArg1, donc nous supprimons l'image actuelle (méthodedoJob):
Maintenantwe’re in the previous method:
Cependant, les arguments d'appel sont déjà calculés à ce stade, donc,we need to drop the current frame as well:
Nous pouvons maintenant relancer le traitement en appelantStep Into.
4. Points de rupture de champ
Parfois, les champs non privés sont modifiés par d’autres classes, non pas via des setters mais directement (c’est le cas avec des bibliothèques tierces où nous ne contrôlons pas le code source).
Dans de telles situations, il peut être difficile de comprendre quand la modification est faite. IntelliJ permet de créer des points d'arrêt au niveau du champ pour suivre cela.
Ils sont configurés comme d'habitude - faites un clic gauche sur la gouttière de l'éditeur gauche sur la ligne du champ. Après cela, il est possible deopen breakpoint properties (right-click on the breakpoint mark) and configure if we’re interested in the field’s reads, writes, or both:
5. Journalisation des points d'arrêt
Parfois, nous savons qu'il existe une condition de concurrence dans l'application, mais nous ne savons pas où elle se trouve exactement. Il peut être difficile de s’y attaquer, surtout lorsqu’on travaille avec un nouveau code.
Nous pouvons ajouter des instructions de débogage aux sources de notre programme. Cependant, une telle capacité n’existe pas pour les bibliothèques tierces.
L'IDE peut aider ici -it allows setting breakpoints that don’t block execution once hit, but produce logging statements instead.
Prenons l'exemple suivant:
public static void main(String[] args) {
ThreadLocalRandom random = ThreadLocalRandom.current();
int count = 0;
for (int i = 0; i < 5; i++) {
if (isInterested(random.nextInt(10))) {
count++;
}
}
System.out.printf("Found %d interested values%n", count);
}
private static boolean isInterested(int i) {
return i % 2 == 0;
}
Supposons que nous souhaitons enregistrer les paramètres réels de l'appelisInterested.
Créons un point d'arrêt non bloquant dans la méthode cible (Shift + clic gauche sur la gouttière gauche de l'éditeur). Après cela, ouvrons ses propriétés (clic droit sur le point d'arrêt) etdefine the target expression to log:
Lors de l'exécution de l'application (notez qu'il est toujours nécessaire d'utiliser le mode Débogage), nous verrons le résultat:
isInterested(1)
isInterested(4)
isInterested(3)
isInterested(1)
isInterested(6)
Found 2 interested values
6. Points d'arrêt conditionnels
Nous pouvons avoir une situation où une méthode particulière est appelée à partir de plusieurs threads simultanément et nous devons déboguer le traitement uniquement pour un argument particulier.
IntelliJ autorisecreating breakpoints that pause the execution only if a user-defined condition is satisfied.
Voici un exemple qui utilise le code source ci-dessus:
Désormais, le débogueur s’arrêtera sur le point d’arrêt uniquement si l’argument donné est supérieur à 3.
7. Marques d'objets
C'est la fonctionnalité IntelliJ la plus puissante et la moins connue. C’est assez simple dans l’essence -we can attach custom labels to JVM objects.
Jetons un coup d'œil à une application que nous utiliserons pour les démontrer:
public class Test {
public static void main(String[] args) {
Collection tasks = Arrays.asList(new Task(), new Task());
tasks.forEach(task -> new Thread(task).start());
}
private static void mayBeAdd(Collection holder) {
int i = ThreadLocalRandom.current().nextInt(10);
if (i % 3 == 0) {
holder.add(i);
}
}
private static class Task implements Runnable {
private final Collection holder = new ArrayList<>();
@Override
public void run() {
for (int i = 0; i < 20; i++) {
mayBeAdd(holder);
}
}
}
}
7.1. Créer des marques
Un objet peut être marqué lorsqu'une application est arrêtée sur un point d'arrêt et que la cible est accessible à partir de cadres de pile.
Sélectionnez-le, appuyez surF11 (actionMark Object) et définissez le nom de la cible:
7.2. Afficher les marques
Nous pouvons maintenant voir nos étiquettes d'objet personnalisé même dans d'autres parties de l'application:
Ce qui est cool, c'est queeven if a marked object is not reachable from stack frames at the moment, we can still see its state - ouvre une boîte de dialogueEvaluate Expression ou ajoute une nouvelle montre et commence à taper le nom de la marque.
IntelliJ propose de le compléter avec le suffixe_DebugLabel:
Lorsque nous l'évaluons, l'état de l'objet cible est affiché:
8. Conclusion
Nous avons vérifié un certain nombre de techniques qui augmentent considérablement la productivité lors du débogage d’une application multithread.
C’est généralement une tâche difficile, et nous ne pouvons pas sous-estimer l’importance de l’aide des outils ici.