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:
- Melacak panggilan sistem dengan strace.
- Menemukan bug memori dengan malloc debug atau Address Sanitizer (ASan).
- Membuat profil dengan Simpleperf.
Menggunakan skrip shell wrap
Menggunakan wrap.sh
itu mudah:
- 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).
- Skrip shell bernama
- Instal APK yang dapat di-debug di perangkat.
- 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:
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