ndk-gdb

L'NDK include uno script shell denominato ndk-gdb per avviare una sessione di debug nativo con la riga di comando. Gli utenti che preferiscono utilizzare una GUI dovrebbero leggere la documentazione relativa al debug in Android Studio.

Requisiti

Affinché il debug nativo della riga di comando funzioni, devono essere soddisfatti i seguenti requisiti:

  • Crea la tua app utilizzando lo script ndk-build. Lo script ndk-gdb non supporta l'utilizzo del metodo make APP=<name> precedente per la creazione.
  • Attiva il debug delle app nel file AndroidManifest.xml includendo un elemento <application> che imposti l'attributo android:debuggable su true.
  • Crea la tua app per eseguirla su Android 2.2 (livello API Android 8) o versioni successive.
  • Esegui il debug su un dispositivo o emulatore con Android 2.2 o versioni successive. A scopo di debug, il livello API target dichiarato nel file AndroidManifest.xml non è importante.
  • Sviluppa la tua app in una shell Unix. Su Windows, utilizza Cygwin o l'implementazione sperimentale ndk-gdb-py Python.
  • Usa GNU Make 3.81 o versioni successive.

Utilizzo

Per richiamare lo script ndk-gdb, passa alla directory dell'applicazione o a una directory secondaria. Ecco alcuni esempi:

cd $PROJECT
$NDK/ndk-gdb

Qui, $PROJECT rimanda alla directory principale del progetto, mentre $NDK al percorso di installazione NDK.

Quando richiami ndk-gdb, configura la sessione in modo da cercare i file di origine e le versioni di simboli/debug delle librerie native generate. Una volta eseguito il collegamento al processo di applicazione, ndk-gdb restituisce una lunga serie di messaggi di errore, indicando che non è in grado di trovare varie librerie di sistema. È normale, perché la macchina host non contiene versioni simboliche/di debug di queste librerie sul dispositivo di destinazione. Puoi tranquillamente ignorare questi messaggi.

Successivamente, ndk-gdb mostra un normale prompt di GDB.

Puoi interagire con ndk-gdb come faresti con GNU GDB. Ad esempio, puoi utilizzare b <location> per impostare punti di interruzione e c (per "continua") per riprendere l'esecuzione. Per un elenco completo dei comandi, consulta il manuale di GDB. Se preferisci utilizzare LLDB Debugger, utilizza l'opzione --lldb quando richiami lo script ndk-gdb.

Tieni presente che, quando esci dal prompt di GDB, il processo dell'applicazione di cui esegui il debug viene interrotto. Questo comportamento è una limitazione di gdb.

ndk-gdb gestisce molte condizioni di errore e, se rileva un problema, visualizza un messaggio informativo. Questi controlli includono: verificare che siano soddisfatte le seguenti condizioni:

  • Verifica che ADB sia presente nel tuo percorso.
  • Verifica che l'applicazione sia dichiarata di cui è possibile eseguire il debug nel file manifest.
  • Verifica che sul dispositivo sia possibile eseguire il debug dell'applicazione installata con lo stesso nome di pacchetto.

Per impostazione predefinita, ndk-gdb cerca un processo di applicazione già in esecuzione e, se non lo trova, visualizza un errore. Tuttavia, puoi utilizzare l'opzione --start o --launch=<name> per avviare automaticamente l'attività prima della sessione di debug. Per ulteriori informazioni, vedi Opzioni.

Opzioni

Per visualizzare un elenco completo delle opzioni, digita ndk-gdb --help nella riga di comando. La tabella 1 mostra alcuni di quelli più utilizzati, insieme a brevi descrizioni.

Tabella 1. Opzioni ndk-gdb comuni e relative descrizioni.

A partire da ndk-gdb con questa opzione specificata viene avviata la prima attività avviabile elencata nel manifest dell'applicazione. Usa --launch=<name> per avviare la prossima attività avviabile. Per eseguire il dump dell'elenco delle attività avviabili, esegui --launch-list dalla riga di comando.

Opzione Descrizione>
--lldb

Se impostato, lo script utilizzerà il debugger LLDB per la sessione anziché gdb.

--verbose

Questa opzione indica al sistema di compilazione di stampare informazioni dettagliate sulla configurazione della sessione di debug nativo. È necessario solo per i problemi di debug quando il debugger non riesce a connettersi all'app e i messaggi di errore visualizzati in ndk-gdb non sono sufficienti.

--force Per impostazione predefinita, ndk-gdb viene interrotta se rileva che un'altra sessione di debug nativa è già in esecuzione sullo stesso dispositivo. Questa opzione termina l'altra sessione e la sostituisce con una nuova. Tieni presente che questa opzione non termina l'app effettiva sottoposta a debug, operazione che devi terminare separatamente.
--start

All'avvio, ndk-gdb prova per impostazione predefinita a collegarsi a un'istanza esistente della tua app in esecuzione sul dispositivo di destinazione. Puoi ignorare questo comportamento predefinito utilizzando --start per avviare esplicitamente l'applicazione sul dispositivo di destinazione prima della sessione di debug.

--launch=<name>

Questa opzione è simile a --start, tranne per il fatto che consente di avviare un'attività specifica dalla tua applicazione. Questa funzionalità è utile solo se il file manifest definisce più attività avviabili.

--launch-list

Questa opzione stampa l'elenco di tutti i nomi delle attività avviabili trovati nel file manifest dell'app. --start usa il nome della prima attività.

--project=<path> Questa opzione specifica la directory del progetto dell'app. È utile se vuoi avviare lo script senza dover prima passare alla directory del progetto.
--port=<port>

Per impostazione predefinita, ndk-gdb usa la porta TCP locale 5039 per comunicare con l'app di cui sta eseguendo il debug sul dispositivo di destinazione. L'utilizzo di una porta diversa consente di eseguire il debug nativo dei programmi in esecuzione su diversi dispositivi o emulatori collegati alla stessa macchina host.

--adb=<file>

Questa opzione specifica l'eseguibile dello strumento adb. È necessario solo se non hai impostato il percorso per includere l'eseguibile.

  • -d
  • -e
  • -s <serial>
  • Questi flag sono simili ai comandi adb con gli stessi nomi. Imposta questi flag se hai diversi dispositivi o emulatori collegati alla macchina host. Di seguito sono riportati i significati:

    -d
    Connettiti a un unico dispositivo fisico.
    -e
    Connettiti a un singolo dispositivo emulatore.
    -s <serial>
    Collegati a un emulatore o un dispositivo specifico. Qui, <serial> è il nome del dispositivo elencato nel comando adb devices.

    In alternativa, puoi definire la variabile di ambiente ADB_SERIAL per elencare un dispositivo specifico, senza la necessità di un'opzione specifica.

  • --exec=<file>
  • -x <file>
  • Questa opzione indica a ndk-gdb di eseguire i comandi di inizializzazione GDB trovati in <file> dopo la connessione al processo di cui è in corso il debug. Questa è una funzionalità utile se vuoi compiere un'azione ripetuta, ad esempio configurare un elenco di punti di interruzione per poi riprendere l'esecuzione automaticamente.

    --nowait

    Disabilita la messa in pausa del codice Java fino alla connessione di GDB. Se superi questa opzione, il debugger potrebbe perdere i punti di interruzione iniziali.

    --tui -t

    Abilita l'interfaccia utente di testo, se disponibile.

    --gnumake-flag=<flag>

    Questa opzione è uno o più flag aggiuntivi da passare al sistema ndk-build durante l'esecuzione di query per ottenere informazioni sul progetto. Puoi utilizzare più istanze di questa opzione nello stesso comando.

    Nota: le ultime tre opzioni in questa tabella si riferiscono solo alla versione Python di ndk-gdb.

    Supporto dei thread

    Se la tua app viene eseguita su una piattaforma precedente ad Android 2.3 (livello API 9), ndk-gdb non può eseguire correttamente il debug dei thread nativi. Il debugger può eseguire il debug solo del thread principale, abd ignora completamente l'esecuzione di altri thread.

    Se inserisci un punto di interruzione su una funzione eseguita su un thread non principale, il programma viene chiuso e GDB visualizza il seguente messaggio:

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