Script shell Wrap

Durante il debug e la profilazione delle app con codice nativo, spesso è utile usare strumenti di debug che devono essere abilitati all'avvio del processo. Ciò richiede esegui l'app seguendo un nuovo processo anziché clonarla dalla zigote. Ecco alcuni esempi:

Utilizzare lo script shell di wrapping

Usare wrap.sh è facile:

  1. Compila un APK personalizzato di cui è possibile eseguire il debug che pacchettizzi quanto segue:
  2. Installa l'APK di cui è possibile eseguire il debug su un dispositivo.
  3. Avvia l'app.

Crea lo script shell di wrapping

Quando avvii un APK di cui è possibile eseguire il debug che contiene wrap.sh, il sistema esegue lo script e passa il comando per avviare l'app come argomenti. Lo script è responsabile dell'avvio dell'app, ma può rendere qualsiasi ambiente o argomento modifiche. Lo script deve seguire Sintassi della shell MirBSD Korn (mksh).

Il seguente snippet mostra come scrivere un file wrap.sh semplice che avvia l'app:

#!/system/bin/sh
exec "$@"

Debug Malloc

Per utilizzare debug malloc tramite wrap.sh, dovresti includere la seguente riga:

#!/system/bin/sh
LIBC_DEBUG_MALLOC_OPTIONS=backtrace logwrapper "$@"

ASan

È disponibile un esempio di come eseguire questa operazione per ASan nel Documentazione ASan.

Pacchetto wrap.sh

Per poter usare wrap.sh, deve essere possibile eseguire il debug del tuo APK. Assicurati che android:debuggable="true"è configurata in <application> nel tuo file manifest Android oppure, se utilizzi Android Studio, che hai configurato una build di debug build.gradle.

È inoltre necessario impostare useLegacyPackaging a true nel file build.gradle dell'app. Nella maggior parte dei casi, questa opzione è impostata a false per impostazione predefinita, quindi ti consigliamo di impostarlo esplicitamente su true per per evitare sorprese.

Devi pacchettizzare lo script wrap.sh con le librerie native dell'app. Se la tua app non contiene librerie native, aggiungi manualmente la directory lib a della directory del progetto. Per ogni architettura supportata dall'app, devi: fornire una copia dello script wrap shell nella directory della libreria nativa.

L'esempio seguente mostra il layout di file per supportare sia ARMv8 che x86-64 delle architetture:

# App Directory
|- AndroidManifest.xml
|- …
|- lib
   |- arm64-v8a
      |- ...
      |- wrap.sh
   |- x86_64
      |- ...
      |- wrap.sh

Android Studio pacchettizza solo i file .so dalle directory lib/, quindi se sei un utente di Android Studio, devi inserire i tuoi file wrap.sh nel src/main/resources/lib/* directory, in modo che vengano pacchettizzate in modo corretto.

Tieni presente che resources/lib/x86 verrà visualizzato nell'UI come lib.x86, ma in realtà dovrebbe essere una sottodirectory:

Esempio di pacchettizzazione di wrap.sh in Android Studio

Esegui il debug quando si utilizza wrap.sh

Se vuoi collegare un debugger quando utilizzi wrap.sh, lo script shell attivare manualmente il debug. Le modalità di esecuzione sono state diverse da un'uscita all'altra, quindi questo esempio mostra come aggiungere le opzioni appropriate per tutte le release che Supporto di wrap.sh:

#!/system/bin/sh

cmd=$1
shift

os_version=$(getprop ro.build.version.sdk)

if [ "$os_version" -eq "27" ]; then
  cmd="$cmd -Xrunjdwp:transport=dt_android_adb,suspend=n,server=y -Xcompiler-option --debuggable $@"
elif [ "$os_version" -eq "28" ]; then
  cmd="$cmd -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y -Xcompiler-option --debuggable $@"
else
  cmd="$cmd -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y $@"
fi

exec $cmd