Déboguer avec des points d'arrêt

1. Avant de commencer

Arrivés à ce stade, il est probable que la plupart des développeurs sachent comment déboguer à l'aide d'instructions de journal. Si vous avez terminé le module 1, vous savez également comment lire les traces de la pile et faire des recherches dans les messages d'erreur. Bien qu'il s'agisse là de deux puissants outils de débogage, les IDE modernes offrent davantage de fonctionnalités pour améliorer l'efficacité de votre processus de débogage.

Dans cette leçon, vous allez découvrir ce qu'est le débogueur intégré d'Android Studio, comment suspendre l'exécution d'une application et comment exécuter le code ligne par ligne pour identifier la source exacte du bug. Vous apprendrez également à utiliser la fonctionnalité Watches et à effectuer le suivi de variables spécifiques sans devoir ajouter d'instructions de journalisation spécifiques.

Conditions préalables

  • Vous savez comment naviguer dans un projet dans Android Studio.
  • Vous maîtrisez la journalisation en langage Kotlin.

Points abordés

  • Comment associer le débogueur à une application en cours d'exécution.
  • Utiliser des points d'arrêt pour mettre en pause une application en cours d'exécution et inspecter le code ligne par ligne.
  • Ajouter des expressions conditionnelles à des points d'arrêt pour accélérer le débogage.
  • Ajouter des variables au volet Watches pour faciliter le débogage.

Ce dont vous avez besoin

  • Un ordinateur sur lequel est installé Android Studio

2. Créer un projet

Plutôt que de déboguer une application volumineuse et complexe, nous allons commencer par un projet vide et introduire du code comportant des bugs pour faire la démonstration des outils de débogage d'Android Studio.

Commencez par créer un projet Android Studio.

  1. Sur l'écran Sélectionner un modèle de projet, choisissez Activité vide.

a949156bcfbf8a56.png

  1. Nommez l'application Débogage et assurez-vous que le langage est défini sur Kotlin. Ne modifiez pas les autres champs.

9863157e10628a87.png

  1. Un nouveau projet Android Studio vous est proposé. Il affiche un fichier nommé MainActivity.kt.

e3ab4a557c50b9b0.png

Introduire un bug

Vous vous souvenez de l'exemple de division par zéro présenté dans la leçon sur le débogage du module 1 ? Dans la dernière itération de la boucle, lorsque l'application tente d'effectuer une division par zéro, elle plante avec java.langArithmeticException, car il est impossible de diviser par zéro. Ce bug a été trouvé et corrigé en examinant la trace de la pile, et cette hypothèse a été validée à l'aide d'instructions de journalisation.

Comme vous connaissez déjà cet exemple, nous nous en servirons pour montrer comment utiliser des points d'arrêt. Les points d'arrêt parcourent le code ligne par ligne, sans qu'il soit nécessaire d'ajouter des instructions de journalisation, ni de réexécuter votre application au préalable.

  1. Ouvrez MainActivity.kt et remplacez le code par ce qui suit :
package com.example.myapplication

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

public val TAG = "MainActivity"

class MainActivity : AppCompatActivity() {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)
       division()
   }

   fun division() {
       val numerator = 60
       var denominator = 4
       repeat(5) {
           Log.v(TAG, "${numerator / denominator}")
           denominator--
       }
   }

}
  1. Exécutez l'application. Notez que l'application plante comme prévu.

9468226e5f4d5729.png

3. Déboguer avec des points d'arrêt

Lorsque vous avez découvert la journalisation, vous avez appris à placer des journaux de manière stratégique pour identifier les bugs et vérifier qu'ils ont bien été corrigés. Toutefois, lorsque vous rencontrez des bugs que vous n'avez pas introduits, il n'est pas toujours évident de savoir où placer les instructions de journalisation ou quelles variables imprimer. Souvent, ces informations ne sont disponibles qu'au moment de l'exécution.

fun division() {
    val numerator = 60
    var denominator = 4
    repeat(5) {
        Log.v(TAG, "${numerator / denominator}")
        denominator--
    }
}

C'est là que les points d'arrêt entrent en jeu. Même si vous n'avez qu'une vague idée de l'origine du bug sur la base des informations figurant dans la trace de la pile, vous pouvez ajouter un point d'arrêt qui fait office de panneau d'arrêt pour une ligne de code spécifique. Une fois le point d'arrêt atteint, l'exécution est suspendue, ce qui vous permet d'utiliser d'autres outils de débogage au moment de l'exécution pour obtenir une vue précise de ce qui se passe et de ce qui ne va pas.

Associer le débogueur

En arrière-plan, Android Studio utilise un outil appelé Android Debug Bridge, également connu sous sa forme abrégée ADB. Cet outil de ligne de commande est intégré à Android Studio et fournit des fonctionnalités de débogage (telles que des points d'arrêt) à vos applications en cours d'exécution. Les outils de débogage sont souvent appelés débogueurs.

Pour utiliser le débogueur ou l'associer à une application, vous ne pouvez pas simplement exécuter l'application en sélectionnant Exécuter > Exécuter, comme auparavant, mais vous devez utiliser Exécuter > Déboguer l'application.

340a8e850b3c86d3.png

Ajouter des points d'arrêt à votre projet

Pour voir les points d'arrêt en action, procédez comme suit :

  1. Ajoutez un point d'arrêt en cliquant dans la marge à côté du numéro de ligne au niveau duquel effectuer la pause. Un point apparaît à côté du numéro de ligne et la ligne est mise en surbrillance.

629ac33dfb3873e.png

  1. Exécutez votre application avec le débogueur associé. Pour cela, utilisez Run > Debug 'app' ou l'icône a71c8b295db5927d.png dans la barre d'outils. Au lancement de l'application, l'écran suivant doit s'afficher :

3bd9cbe69d5a0d0e.png

Une fois l'application lancée, le point d'arrêt est mis en surbrillance lors de son activation.

928fc1194966c9.png

Un nouvel onglet Débogage s'ouvre au bas de l'écran où la fenêtre Logcat était précédemment affichée.

447d9743c118babd.png

Sur la gauche se trouve une liste de fonctions (les mêmes que celles figurant dans la liste affichée dans la trace de la pile). Le volet de droite vous permet de vérifier les valeurs des différentes variables de la fonction actuelle (division()). En haut de l'écran, des boutons vous permettent de naviguer dans votre programme lorsque l'exécution est suspendue. Le bouton que vous utiliserez le plus souvent est Passer, qui exécute la ligne de code mise en surbrillance.

48219b96d5ab6ba6.png

Pour déboguer le code, procédez comme suit :

  1. Une fois le point d'arrêt atteint, la ligne 19 (qui déclare la variable numerator) est mise en surbrillance, mais elle n'a pas encore été exécutée. Utilisez le bouton Passer fbdcba647f9844c4.png pour exécuter la ligne 19. La ligne 20 apparaît maintenant en surbrillance.

eaacf76805166461.png

  1. Définissez un point d'arrêt à la ligne 22. C'est à ce niveau que la division a eu lieu et que la trace de la pile a signalé l'exception.

1f18ab31dc58a1a7.png

  1. Utilisez le bouton Reprendre le programme 616d16841834ae2a.png à gauche de la fenêtre Débogage pour accéder au point d'arrêt suivant. Exécutez le reste de la fonction division().

3a9c3edc893f9720.png

  1. Notez que l'exécution s'arrête à la ligne 17, avant de l'exécuter.

aa56331ad870cd40.png

  1. Les valeurs de chaque variable numerator et denominator sont affichées à côté de leurs déclarations. Les valeurs des variables sont visibles dans la fenêtre de débogage de l'onglet Variables.

5b3515c5580ee7dd.png

  1. Appuyez encore quatre fois sur le bouton Resume Program (Reprendre le programme) à gauche de la fenêtre de débogage. À chaque fois, la boucle s'interrompt et observe les valeurs de numerator et denominator. Lors de la dernière itération, numerator doit être 60, et denominator doit être 0. Et vous ne pouvez pas diviser 60 par 0 !

56ea223612b88125.png

Désormais, vous connaissez précisément la ligne de code à l'origine du bug, ainsi que la raison exacte du problème. Comme précédemment, vous pouvez corriger le bug en modifiant le nombre de répétitions du code, qui passe de 5 à 4.

fun division() {
    val numerator = 60
    var denominator = 4
    repeat(4) {
        Log.v(TAG, "${numerator / denominator}")
        denominator--
    }
}

4. Définir des conditions pour les points d'arrêt

Dans la section précédente, vous deviez parcourir chaque itération de la boucle jusqu'à ce que le dénominateur soit égal à zéro. Dans les applications plus complexes, cela peut s'avérer fastidieux si vous disposez de moins d'informations sur le bug. Toutefois, si vous avez une hypothèse (par exemple, l'application plante uniquement lorsque le dénominateur est égal à zéro), vous pouvez modifier le point d'arrêt de sorte qu'il ne soit atteint que lorsque cette hypothèse se vérifie, au lieu de devoir parcourir chaque itération en boucle.

  1. Si nécessaire, introduisez à nouveau le bug en remplaçant 4 par 5 dans la boucle de répétition.
repeat(4) {
    ...
}
  1. Placez un nouveau point d'arrêt sur la ligne avec l'instruction repeat.

47fcc3aeb814a9d7.png

  1. Effectuez un clic droit sur l'icône de point d'arrêt rouge. Un menu s'affiche avec quelques options permettant, par exemple, d'activer ou non le point d'arrêt. Il existe toujours un point d'arrêt désactivé, mais il ne se déclenche pas au moment de l'exécution. Vous avez également la possibilité d'ajouter une expression Kotlin qui, si elle prend la valeur "True", déclenche le point d'arrêt. Par exemple, si vous avez utilisé l'expression denominator > 3, le point d'arrêt n'est déclenché que lors de la première itération de la boucle. Pour que le point d'arrêt ne soit déclenché que lorsque votre application est susceptible d'effectuer une division par zéro, définissez l'expression sur denominator == 0. Les options du point d'arrêt doivent se présenter comme suit :

76045ef783d5389b.png

  1. Sélectionnez Exécuter > Déboguer l'Application pour exécuter votre application et vérifiez que le point d'arrêt est atteint.

74ba264a6eab7db7.png

Comme vous pouvez le voir, le dénominateur est déjà égal à 0. Le point d'arrêt n'a été déclenché que lorsque la condition était remplie, ce qui vous permet de parcourir le code plus rapidement et plus facilement.

153be06e8a19e61d.png

  1. Ici encore, vous constatez que le bug est causé par un nombre d'exécutions trop élevé de la boucle, alors que le dénominateur était défini sur 0.

Ajouter des variables Watch

Si vous souhaitez surveiller une valeur spécifique pendant le débogage, il n'est pas nécessaire de parcourir l'onglet Variables pour la trouver. Pour ce faire, vous pouvez en effet ajouter ce que l'on appelle des Watches. Ces variables sont visibles dans le volet de débogage. Lorsque l'exécution est suspendue et que cette variable entre dans le champ d'application, elle est visible dans le volet "Watches". Cela améliore l'efficacité du débogage lorsque vous travaillez sur des projets plus importants. Vous pourrez effectuer le suivi de toutes les variables pertinentes au même endroit.

  1. Dans la vue de débogage, un autre volet vide intitulé Watches est normalement visible à droite du volet des variables. Cliquez sur le bouton Plus c97b1f6a879b0563.png dans l'angle supérieur gauche. L'option de menu New Watch s'affiche alors.

4d27cc7c5222377b.png

  1. Saisissez le nom de la variable, denominator, dans le champ prévu à cet effet, puis appuyez sur Entrée.
  2. Exécutez à nouveau votre application en sélectionnant Run > debug 'app'. Lorsque le point d'arrêt est atteint, la valeur du dénominateur s'affiche alors dans le volet "Watches".

5. Félicitations

En résumé :

  • Vous pouvez définir des points d'arrêt pour suspendre l'exécution de votre application.
  • Lorsque l'exécution est suspendue, vous pouvez "passer outre" pour n'exécuter qu'une seule ligne de code.
  • Vous pouvez définir des instructions conditionnelles pour ne déclencher les points d'arrêt qu'en fonction d'une expression Kotlin.
  • Les Watches vous permettent de regrouper des variables d'intérêt lors du débogage.

En savoir plus