ndk-gdb

Das NDK enthält ein Shell-Skript mit dem Namen ndk-gdb, um eine native Debugging-Sitzung für die Befehlszeile zu starten. Nutzer, die lieber eine grafische Benutzeroberfläche verwenden, sollten stattdessen die Dokumentation zur Fehlerbehebung in Android Studio lesen.

Voraussetzungen

Damit das native Debugging über die Befehlszeile funktioniert, müssen folgende Anforderungen erfüllt sein:

  • Erstellen Sie Ihre Anwendung mit dem Skript ndk-build. Das Skript ndk-gdb unterstützt nicht die Legacy-Methode make APP=<name> zum Erstellen von Builds.
  • Aktivieren Sie das App-Debugging in der Datei AndroidManifest.xml. Fügen Sie dazu ein <application>-Element ein, das das Attribut android:debuggable auf true setzt.
  • Entwickeln Sie Ihre App für die Ausführung unter Android 2.2 (Android API-Level 8) oder höher.
  • Beheben Sie Fehler auf einem Gerät oder Emulator mit Android 2.2 oder höher. Für die Fehlerbehebung spielt das Ziel-API-Level, das Sie in der Datei AndroidManifest.xml angeben, keine Rolle.
  • Anwendung in einer Unix-Shell entwickeln Verwenden Sie unter Windows Cygwin oder die experimentelle ndk-gdb-py Python-Implementierung.
  • Verwenden Sie GNU Make 3.81 oder höher.

Nutzung

Wechseln Sie zum Aufrufen des Skripts ndk-gdb in das Anwendungsverzeichnis oder ein untergeordnetes Verzeichnis. Beispiele:

cd $PROJECT
$NDK/ndk-gdb

Hier verweist $PROJECT auf das Stammverzeichnis Ihres Projekts und $NDK auf Ihren NDK-Installationspfad.

Wenn Sie ndk-gdb aufrufen, wird die Sitzung so konfiguriert, dass nach den Quelldateien und Symbol-/Debug-Versionen der generierten nativen Bibliotheken gesucht wird. Nach dem erfolgreichen Anhängen an Ihren Anwendungsprozess gibt ndk-gdb eine lange Reihe von Fehlermeldungen aus, wobei darauf hingewiesen wird, dass keine verschiedenen Systembibliotheken gefunden werden können. Das ist normal, da Ihr Hostcomputer auf dem Zielgerät keine Symbol- bzw. Debug-Versionen dieser Bibliotheken enthält. Sie können diese Meldungen ignorieren.

Als Nächstes zeigt ndk-gdb eine normale GDB-Eingabeaufforderung an.

Sie interagieren mit ndk-gdb auf dieselbe Weise wie mit GNU GDB. Sie können beispielsweise b <location> verwenden, um Haltepunkte festzulegen, und c (für „Weiter“), um die Ausführung fortzusetzen. Eine umfassende Liste der Befehle finden Sie im GDB-Handbuch. Wenn Sie lieber den LLDB Debugger verwenden möchten, nutzen Sie beim Aufrufen des Skripts ndk-gdb die Option --lldb.

Wenn Sie die GDB-Eingabeaufforderung schließen, wird der Anwendungsprozess beendet, den Sie debuggen. Dieses Verhalten stellt eine gdb-Einschränkung dar.

ndk-gdb verarbeitet viele Fehlerbedingungen und zeigt eine informative Fehlermeldung an, wenn ein Problem festgestellt wird. Dabei wird unter anderem geprüft, ob die folgenden Bedingungen erfüllt sind:

  • Prüft, ob sich ADB im Pfad befindet.
  • Prüft, ob deine App in ihrem Manifest als debug-fähig deklariert ist.
  • Prüft, ob die auf dem Gerät installierte App mit demselben Paketnamen auch debugfähig ist.

Standardmäßig sucht ndk-gdb nach einem bereits ausgeführten Anwendungsprozess und zeigt einen Fehler an, wenn kein Prozess vorhanden ist. Sie können jedoch mit der Option --start oder --launch=<name> Ihre Aktivität vor der Debugging-Sitzung automatisch starten. Weitere Informationen finden Sie unter Optionen.

Optionen

Geben Sie ndk-gdb --help in die Befehlszeile ein, um eine vollständige Liste der Optionen aufzurufen. In Tabelle 1 sind einige der am häufigsten verwendeten Begriffe sowie kurze Beschreibungen aufgeführt.

Tabelle 1 Allgemeine ndk-gdb-Optionen und ihre Beschreibungen.

Wenn Sie ndk-gdb mit der angegebenen Option starten, wird die erste ausführbare Aktivität gestartet, die in Ihrem Anwendungsmanifest aufgeführt ist. Verwenden Sie --launch=<name>, um die nächste startbare Aktivität zu starten. Führen Sie --launch-list über die Befehlszeile aus, um die Liste der startbaren Aktivitäten zu löschen.

Option Beschreibung>
--lldb

Wenn festgelegt, verwendet das Skript für die Sitzung den LLDB-Debugger anstelle von gdb.

--verbose

Mit dieser Option wird das Build-System angewiesen, ausführliche Informationen zur Einrichtung der nativen Fehlerbehebungssitzung auszudrucken. Dies ist nur für die Fehlerbehebung erforderlich, wenn der Debugger keine Verbindung zur Anwendung herstellen kann und die von ndk-gdb angezeigten Fehlermeldungen nicht ausreichen.

--force Standardmäßig wird ndk-gdb abgebrochen, wenn bereits eine andere native Debugging-Sitzung auf demselben Gerät ausgeführt wird. Mit dieser Option wird die andere Sitzung beendet und durch eine neue ersetzt. Beachten Sie, dass diese Option die eigentliche Anwendung, die debuggen wird, nicht beendet. Sie müssen dies separat beenden.
--start

Wenn Sie ndk-gdb starten, wird standardmäßig versucht, eine Verbindung zu einer vorhandenen laufenden Instanz Ihrer App auf dem Zielgerät herzustellen. Sie können dieses Standardverhalten überschreiben, indem Sie die Anwendung mit --start vor der Fehlerbehebungssitzung explizit auf dem Zielgerät starten.

--launch=<name>

Diese Option ähnelt --start, mit dem Unterschied, dass Sie damit eine bestimmte Aktivität aus Ihrer Anwendung starten können. Diese Funktion ist nur nützlich, wenn in Ihrem Manifest mehrere startbare Aktivitäten definiert sind.

--launch-list

Mit dieser praktischen Option wird eine Liste aller ausführbaren Aktivitätsnamen aus deinem App-Manifest ausgegeben. --start verwendet den Namen der ersten Aktivität.

--project=<path> Diese Option gibt das Anwendungsprojektverzeichnis an. Dies ist nützlich, wenn Sie das Skript starten möchten, ohne zuerst zum Projektverzeichnis wechseln zu müssen.
--port=<port>

Standardmäßig verwendet ndk-gdb den lokalen TCP-Port 5039, um mit der App zu kommunizieren, für die die Fehlerbehebung auf dem Zielgerät durchgeführt wird. Wenn Sie einen anderen Port verwenden, können Sie Programme nativ debuggen, die auf verschiedenen Geräten ausgeführt werden, oder Emulatoren, die mit demselben Hostcomputer verbunden sind.

--adb=<file>

Mit dieser Option wird die ausführbare Datei des adb-Tools angegeben. Dies ist nur erforderlich, wenn Sie den Pfad nicht so eingestellt haben, dass diese ausführbare Datei eingeschlossen wird.

  • -d
  • -e
  • -s <serial>
  • Diese Flags ähneln den ADB-Befehlen mit demselben Namen. Legen Sie diese Flags fest, wenn mehrere Geräte oder Emulatoren mit Ihrem Hostcomputer verbunden sind. Ihre Bedeutungen sind:

    -d
    Mit einem einzelnen physischen Gerät verbinden
    -e
    Mit einem einzelnen Emulatorgerät verbinden.
    -s <serial>
    Verbindung zu einem bestimmten Gerät oder Emulator herstellen Hier ist <serial> der Name des Geräts, wie im Befehl adb devices angegeben.

    Alternativ können Sie die Umgebungsvariable ADB_SERIAL definieren, um ein bestimmtes Gerät aufzulisten, ohne dass eine bestimmte Option erforderlich ist.

  • --exec=<file>
  • -x <file>
  • Mit dieser Option wird ndk-gdb angewiesen, die in <file> gefundenen GDB-Initialisierungsbefehle auszuführen, nachdem eine Verbindung zum Prozess hergestellt wurde, für den eine Fehlerbehebung durchgeführt wird. Diese Funktion ist nützlich, wenn Sie eine Aktion wiederholt ausführen möchten, z. B. eine Liste von Haltepunkten einrichten und die Ausführung dann automatisch fortsetzen möchten.

    --nowait

    Pausieren des Java-Codes deaktivieren, bis GDB verbunden wird Wenn Sie diese Option übergeben, werden dem Debugger möglicherweise frühe Haltepunkte übersehen.

    --tui -t

    Aktiviere die Text-Benutzeroberfläche, falls verfügbar.

    --gnumake-flag=<flag>

    Diese Option ist ein oder mehrere zusätzliche Flags, die bei der Abfrage von Projektinformationen an das ndk-build-System übergeben werden. Sie können mehrere Instanzen dieser Option im selben Befehl verwenden.

    Hinweis : Die letzten drei Optionen in dieser Tabelle gelten nur für die Python-Version von ndk-gdb.

    Thread-Unterstützung

    Wenn Ihre App auf einer älteren Plattform als Android 2.3 (API-Level 9) ausgeführt wird, kann ndk-gdb native Threads nicht richtig debuggen. Der Debugger kann nur Fehler im Hauptthread beheben. Abd ignoriert die Ausführung anderer Threads vollständig.

    Wenn Sie einen Haltepunkt für eine Funktion festlegen, die in einem Nicht-Hauptthread ausgeführt wird, wird das Programm beendet und GDB zeigt die folgende Meldung an:

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