ndk-gdb

Le NDK comprend un script shell nommé ndk-gdb pour lancer une session de débogage native sur la ligne de commande. Si vous préférez utiliser une interface utilisateur graphique (IUG), consultez la documentation sur le débogage dans Android Studio.

Conditions requises

Pour que le débogage natif sur la ligne de commande fonctionne, les conditions suivantes doivent être remplies :

  • Créez votre application à l'aide du script ndk-build. Le script ndk-gdb ne permet pas d'effectuer la compilation à l'aide de l'ancienne méthode make APP=<name>.
  • Pour activer le débogage de l'application dans votre fichier AndroidManifest.xml, ajoutez un élément <application> qui définit l'attribut android:debuggable sur true.
  • Créez votre application pour qu'elle s'exécute sur Android 2.2 (niveau d'API Android 8) ou version ultérieure.
  • Effectuer le débogage sur un appareil ou dans un émulateur exécutant Android 2.2 ou version ultérieure Le niveau d'API cible que vous déclarez dans le fichier AndroidManifest.xml n'a pas d'importance pour le débogage.
  • Développez votre application dans une interface système Unix. Sous Windows, utilisez Cygwin ou l'implémentation expérimentale ndk-gdb-py Python.
  • Utilisez GNU Make 3.81 ou une version ultérieure.

Utilisation

Pour appeler le script ndk-gdb, accédez au répertoire de l'application ou à tout répertoire sous-jacent. Exemple :

cd $PROJECT
$NDK/ndk-gdb

Ici, $PROJECT renvoie vers le répertoire racine de votre projet, et $NDK pointe vers le chemin d'installation du NDK.

Lorsque vous appelez ndk-gdb, il configure la session pour rechercher vos fichiers sources et les versions de symboles ou de débogage des bibliothèques natives que vous avez générées. Lors de l'association à votre processus d'application, ndk-gdb génère une longue série de messages d'erreur, indiquant qu'il ne trouve pas différentes bibliothèques système. Cela est normal, car la machine hôte ne contient pas de versions de symboles ni de débogage de ces bibliothèques sur l'appareil cible. Vous pouvez ignorer ces messages.

ndk-gdb affiche ensuite une invite GDB normale.

Vous interagissez avec ndk-gdb de la même manière que vous le feriez avec GNU GDB. Par exemple, vous pouvez utiliser b <location> pour définir des points d'arrêt et c (qui correspond à "continuer") pour reprendre l'exécution. Pour obtenir la liste complète des commandes, consultez le manuel GDB. Si vous préférez utiliser LLDB Debugger, utilisez l'option --lldb lorsque vous appelez le script ndk-gdb.

Notez que lorsque vous quittez l'invite GDB, le processus applicatif que vous déboguez s'arrête. Ce comportement est une limitation de GDB.

ndk-gdb gère de nombreuses conditions d'erreur et affiche un message d'erreur informatif en cas de problème. Ces vérifications consistent entre autres à s'assurer que les conditions suivantes sont remplies :

  • Vérifie qu'ADB se trouve sous votre chemin d'accès.
  • Vérifie que votre application est déclarée comme débogable dans son fichier manifeste.
  • Vérifie que, sur l'appareil, l'application installée portant le même nom de package est également débogable.

Par défaut, ndk-gdb recherche un processus d'application en cours d'exécution et affiche une erreur s'il ne le trouve pas. Toutefois, vous pouvez utiliser l'option --start ou --launch=<name> pour démarrer automatiquement l'activité avant la session de débogage. Pour en savoir plus, consultez la section Options.

Options

Pour obtenir la liste complète des options, saisissez ndk-gdb --help sur la ligne de commande. Le tableau 1 présente quelques-unes des options les plus courantes et fournit une brève description.

Tableau 1. Options ndk-gdb courantes et description

Le lancement de ndk-gdb lorsque cette option est spécifiée permet d'initier la première activité disponible dans le fichier manifeste de votre application. Utilisez --launch=<name> pour lancer la prochaine activité disponible. Pour vider la liste des activités qui peuvent être lancées, exécutez --launch-list à partir de la ligne de commande.

Option Description >
--lldb

Si cette option est définie, le script utilisera LLDB Debugger pour la session au lieu de gdb.

--verbose

Cette option indique au système de compilation d'imprimer des informations détaillées sur la configuration de la session de débogage native. Elle n'est nécessaire que pour les problèmes de débogage lorsque le débogueur ne parvient pas à se connecter à l'application et que les messages d'erreur affichés par ndk-gdb ne sont pas suffisants.

--force Par défaut, ndk-gdb abandonne s'il détecte qu'une autre session de débogage native est déjà en cours d'exécution sur le même appareil. Cette option supprime l'autre session et la remplace par une nouvelle. Notez que cette option n'arrête pas l'application en cours de débogage, que vous devez fermer séparément.
--start

Lorsque vous démarrez ndk-gdb, il tente par défaut de s'associer à une instance en cours d'exécution de votre application sur l'appareil cible. Vous pouvez ignorer ce comportement par défaut en utilisant --start pour lancer explicitement l'application sur l'appareil cible avant la session de débogage.

--launch=<name>

Cette option est semblable à --start, sauf qu'elle vous permet de démarrer une activité spécifique depuis votre application. Cette fonctionnalité n'est utile que si votre fichier manifeste définit plusieurs activités pouvant être lancées.

--launch-list

Cette option affiche la liste des noms de toutes les activités pouvant être lancées qui se trouvent dans le fichier manifeste de votre application. --start utilise le nom de la première activité.

--project=<path> Cette option spécifie le répertoire du projet de l'application. Elle est utile si vous souhaitez lancer le script sans avoir à passer au préalable au répertoire du projet.
--port=<port>

Par défaut, ndk-gdb utilise le port TCP 5039 local pour communiquer avec l'application qu'il débogue sur l'appareil cible. L'utilisation d'un autre port vous permet de déboguer de manière native des programmes exécutés sur différents appareils ou émulateurs connectés à la même machine hôte.

--adb=<file>

Cette option spécifie l'exécutable de l'outil adb. Elle n'est nécessaire que si vous n'avez pas défini votre chemin pour qu'il inclue cet exécutable.

  • -d
  • -e
  • -s <serial>
  • Ces indicateurs sont semblables aux commandes adb qui portent les mêmes noms. Définissez ces indicateurs si plusieurs appareils ou émulateurs sont connectés à votre machine hôte. Voici leur signification :

    -d
    Connectez-vous à un seul appareil physique.
    -e
    Connectez-vous à un seul appareil d'émulateur.
    -s <serial>
    Connectez-vous à un appareil ou à un émulateur spécifique. Ici, <serial> est le nom de l'appareil tel qu'il est répertorié par la commande adb devices.

    Vous pouvez également définir la variable d'environnement ADB_SERIAL de sorte à afficher un appareil spécifique, sans avoir besoin d'une option spécifique.

  • --exec=<file>
  • -x <file>
  • Cette option indique à ndk-gdb d'exécuter les commandes d'initialisation GDB trouvées dans <file> une fois connecté au processus qu'il débogue. Elle est particulièrement utile si vous souhaitez effectuer une action répétée, par exemple pour établir une liste de points d'arrêt, puis reprendre l'exécution automatiquement.

    --nowait

    Désactivez la mise en veille du code Java jusqu'à ce que GDB se connecte. Si vous ignorez cette option, le débogueur risque de manquer des points d'arrêt à un stade précoce.

    --tui -t

    Activez l'interface utilisateur textuelle (si disponible).

    --gnumake-flag=<flag>

    Cette option correspond à un ou plusieurs indicateurs supplémentaires à transmettre au système ndk-build lors de l'interrogation des informations du projet. Vous pouvez utiliser plusieurs occurrences de cette option dans la même commande.

    Remarque : Les trois dernières options de ce tableau ne concernent que la version Python de ndk-gdb.

    Compatibilité des threads

    Si votre application s'exécute sur une plate-forme antérieure à Android 2.3 (niveau d'API 9), ndk-gdb ne peut pas déboguer correctement les threads natifs. Le débogueur ne peut déboguer que le thread principal et ignore l'exécution des autres threads.

    Si vous placez un point d'arrêt au niveau d'une fonction exécutée sur un thread non principal, le programme se ferme, et GDB affiche le message suivant :

    Program terminated with signal SIGTRAP, Trace/breakpoint trap.
          The program no longer exists.