Di Android 8.0 dan yang lebih tinggi, ART Tooling Interface (ART TI) mengekspos internal runtime tertentu, dan memungkinkan profiler dan debugger perilaku runtime aplikasi. Model ini dapat digunakan untuk mengimplementasikan alat performa tercanggih yang disediakan untuk mengimplementasikan agen native di platform lain.
Internal runtime terekspos ke agen yang telah dimuat ke dalam proses runtime.
Keduanya berkomunikasi dengan ART melalui panggilan langsung dan callback. Runtime
mendukung banyak agen sehingga masalah pembuatan profil ortogonal yang berbeda
akan dipisahkan. Agen dapat disediakan saat runtime dimulai (saat
dalvikvm
atau app_process
dipanggil), atau dilampirkan ke
proses yang sudah berjalan.
Karena kemampuan menginstrumentasikan dan memodifikasi perilaku aplikasi dan runtime sangat ampuh, dua langkah keamanan telah diintegrasikan ke dalam ART TI:
- Pertama, kode yang mengekspos antarmuka agen, JVMTI, diimplementasikan sebagai plugin runtime, bukan komponen inti runtime. Plugin mungkin sedang dimuat dibatasi, sehingga agen dapat diblokir agar tidak menemukan antarmuka poin.
- Kedua, class
ActivityManager
dan proses runtime hanya mengizinkan agen untuk melekatkan ke aplikasi yang dapat di-debug. Aplikasi yang dapat di-debug telah ditandatangani developer mereka untuk dianalisis dan diinstrumentasikan, dan tidak didistribusikan ke pengguna akhir. Google Play Store tidak mengizinkan distribusi file yang dapat di-debug aplikasi. Hal ini memastikan aplikasi normal (termasuk komponen inti) tidak dapat diinstrumentasikan atau dimanipulasi.
Desain
Alur umum dan interkoneksi dalam aplikasi berinstrumen ditampilkan dalam Gambar 1.
Plugin ART libopenjdkjvmti
mengekspos ART TI, yang
dirancang untuk mengakomodasi kebutuhan dan kendala platform:
- Definisi ulang class didasarkan pada file
Dex
, yang hanya berisi definisi kelas tunggal, alih-alih file kelas. - API berbahasa Java untuk instrumentasi dan definisi ulang tidak terbuka.
ART TI juga mendukung profiler Android Studio.
Memuat atau melampirkan agen
Untuk melampirkan agen saat memulai runtime, gunakan perintah ini untuk memuat Plugin JVMTI dan agen yang diberikan:
dalvikvm -Xplugin:libopenjdkjvmti.so -agentpath:/path/to/agent/libagent.so …
Tidak ada langkah-langkah keamanan yang diterapkan saat agen dimuat saat runtime sehingga perlu diingat bahwa runtime yang dimulai secara manual memungkinkan modifikasi tanpa langkah-langkah keamanan. (Hal ini memungkinkan pengujian ART.)
Catatan: Ini tidak berlaku untuk aplikasi normal (termasuk sistem server) di perangkat. Aplikasi diambil dari zygote yang sudah berjalan, dan proses zygote tidak diizinkan untuk memuat agen.
Untuk memasang agen ke aplikasi yang sudah berjalan, gunakan ini berikut:
adb shell cmd activity attach-agent [process] /path/to/agent/libagent.so[=agent-options]
Jika plugin JVMTI belum dimuat, melampirkan agen akan memuat plugin dan library agent.
Agen hanya dapat dilampirkan ke aplikasi yang sedang berjalan yang ditandai sebagai
debuggable (bagian dari manifes aplikasi, dengan atribut
android:debuggable
ditetapkan ke true
di aplikasi
). Class ActivityManager
dan ART memiliki performa
pemeriksaan sebelum mengizinkan agen untuk dilampirkan. ActivityManager
memeriksa informasi aplikasi saat ini (berasal dari PackageManager
data class) untuk mengetahui status yang dapat di-debug, dan runtime akan memeriksa statusnya saat ini,
yang disetel saat aplikasi dimulai.
Lokasi agen
Runtime perlu memuat agen ke dalam proses saat ini agar agen
dapat langsung mengikat dan
berkomunikasi dengannya. ART itu sendiri bersifat agnostik
terkait lokasi spesifik tempat agen berasal. String ini digunakan
untuk panggilan dlopen
. Izin sistem file dan kebijakan SELinux
membatasi pemuatan sebenarnya.
Untuk mengirimkan agen yang dapat dijalankan oleh aplikasi yang dapat di-debug, lakukan hal berikut:
- Sematkan agen di direktori library APK aplikasi.
- Gunakan
run-as
untuk menyalin agen ke data aplikasi saat ini.
API
Metode berikut telah ditambahkan ke android.os.Debug
.
/** * Attach a library as a jvmti agent to the current runtime, with the given classloader * determining the library search path. * Note: agents may only be attached to debuggable apps. Otherwise, this function will * throw a SecurityException. * * @param library the library containing the agent. * @param options the options passed to the agent. * @param classLoader the classloader determining the library search path. * * @throws IOException if the agent could not be attached. * @throws a SecurityException if the app is not debuggable. */ public static void attachJvmtiAgent(@NonNull String library, @Nullable String options, @Nullable ClassLoader classLoader) throws IOException {
API Android Lainnya
Perintah Attach-agent dapat dilihat oleh publik. Perintah ini memasang JVMTI agen ke proses yang berjalan:
adb shell 'am attach-agent com.example.android.displayingbitmaps \'/data/data/com.example.android.displayingbitmaps/code_cache/libfieldnulls.so=Ljava/lang/Class;.name:Ljava/lang/String;\''
Perintah am start -P
dan am
start-profiler/stop-profiler
mirip dengan perintah Attach-agent.
JVMTI
Fitur ini mengekspos JVMTI API ke agen (kode native). Hal yang penting kemampuannya mencakup:
- Mendefinisikan ulang class.
- Melacak alokasi objek dan pembersihan sampah memori.
- Melakukan iterasi pada semua objek dalam heap, mengikuti hierarki referensi objek terstruktur dalam jumlah besar.
- Memeriksa stack panggilan Java.
- Menangguhkan (dan melanjutkan) semua thread.
Kemampuan yang berbeda mungkin tersedia pada versi yang berbeda Android.
Kompatibilitas
Fitur ini memerlukan dukungan runtime inti yang hanya tersedia di Android 8.0 dan lebih tinggi. Produsen perangkat tidak perlu membuat perubahan apa pun untuk menerapkan fitur ini. Ini adalah bagian dari AOSP.
Validasi
CTS menguji hal berikut di Android 8 dan yang lebih tinggi:
- Menguji yang dipasang agen ke aplikasi yang dapat di-debug, dan gagal dilampirkan aplikasi yang tidak dapat di-debug.
- Menguji semua JVMTI API yang diimplementasikan
- Menguji bahwa antarmuka biner untuk agen stabil
Pengujian tambahan telah ditambahkan ke Android 9 dan yang lebih tinggi, serta disertakan dalam uji CTS untuk rilis tersebut.