Skrip shell wrap

Saat men-debug dan membuat profil aplikasi dengan kode native, penggunaan alat proses debug yang perlu diaktifkan saat proses dimulai sering kali berguna. Hal ini mengharuskan Anda menjalankan aplikasi dalam proses baru, bukan membuat kloning dari zygote. Contohnya mencakup:

Menggunakan skrip shell wrap

Menggunakan wrap.sh itu mudah:

  1. Kompilasikan APK kustom yang dapat di-debug, yang memaketkan:
    • Skrip shell bernama wrap.sh. Lihat Membuat skrip shell wrap dan Paket wrap.sh untuk detail selengkapnya.
    • Alat tambahan apa pun yang diperlukan skrip shell Anda (seperti biner strace milik Anda sendiri).
  2. Instal APK yang dapat di-debug di perangkat.
  3. Luncurkan aplikasi.

Membuat skrip shell wrap

Saat Anda meluncurkan APK yang dapat di-debug yang berisi wrap.sh, sistem akan menjalankan skrip dan meneruskan perintah untuk memulai aplikasi sebagai argumen. Skrip ini bertanggung jawab memulai aplikasi, tetapi dapat membuat perubahan lingkungan atau argumen apa saja. Skrip ini harus mengikuti sintaks MirBSD Korn shell (mksh).

Cuplikan berikut menunjukkan cara menulis file wrap.sh sederhana yang baru saja memulai aplikasi:

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

Malloc debug

Untuk menggunakan malloc debug melalui wrap.sh, sertakan baris berikut:

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

ASan

Contoh cara melakukan ini untuk ASan tersedia dalam Dokumentasi ASan.

Paket wrap.sh

Untuk memanfaatkan wrap.sh, APK harus dapat di-debug. Pastikan setelan android:debuggable="true" dikonfigurasi dalam elemen <application> di manifes Android Anda, atau jika Anda menggunakan Android Studio, pastikan build debug telah dikonfigurasi dalam file build.gradle.

Anda juga harus menetapkan useLegacyPackaging ke true dalam file build.gradle aplikasi. Pada umumnya, opsi ini ditetapkan ke false secara default sehingga Anda sebaiknya menetapkannya secara eksplisit ke true untuk menghindari hal tak terduga.

Anda harus memaketkan skrip wrap.sh dengan library native aplikasi. Jika aplikasi tidak berisi library native, tambahkan direktori lib ke direktori project secara manual. Untuk setiap arsitektur yang didukung aplikasi Anda, Anda harus menyediakan salinan skrip shell wrap di direktori library native tersebut.

Contoh berikut menunjukkan tata letak file untuk mendukung arsitektur ARMv8 dan x86-64:

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

Android Studio hanya memaketkan file .so dari direktori lib/, jadi jika menggunakan Android Studio, Anda harus menempatkan file wrap.sh dalam direktori src/main/resources/lib/* agar file tersebut dipaketkan dengan benar.

Perhatikan bahwa resources/lib/x86 akan ditampilkan di UI sebagai lib.x86, tetapi sebenarnya harus berupa subdirektori:

Contoh memaketkan wrap.sh di Android Studio

Men-debug saat menggunakan wrap.sh

Jika Anda ingin menambahkan debugger saat menggunakan wrap.sh, skrip shell harus mengaktifkan proses debug secara manual. Cara melakukannya bervariasi antara satu rilis dengan rilis lainnya, sehingga contoh ini menunjukkan cara menambahkan opsi yang sesuai untuk semua rilis yang mendukung 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