In Android 8.0 e versioni successive, ART Tooling Interface (ART TI) espone alcuni componenti interni del runtime e consente ai profiler e ai debugger di influenzare il comportamento di runtime delle app. Può essere usato per implementare all'avanguardia che vengono forniti per implementare su altre piattaforme.
Gli elementi interni del runtime sono esposti agli agenti che sono stati caricati nel processo di runtime.
Queste comunicano con l'ART tramite chiamate dirette e callback. Il runtime
supporta più agenti in modo che diversi problemi di profilazione ortogonale possano
separate. Gli agenti possono essere forniti all'inizio del runtime (quando
dalvikvm
o app_process
sono richiamati) o collegati a
un processo già in esecuzione.
Poiché è possibile instrumentare e modificare il comportamento dell'app e del runtime, molto potente, ART TI ha integrato due misure di sicurezza:
- In primo luogo, il codice che espone l'interfaccia dell'agente, JVMTI, viene implementato come un plug-in di runtime, non un componente fondamentale del runtime. Il caricamento del plug-in potrebbe limitato, in modo che gli agenti non possano trovare qualsiasi interfaccia punti.
- In secondo luogo, sia la classe
ActivityManager
sia il processo di runtime consentono solo agli agenti alle app di cui è possibile eseguire il debug. Le app di debug sono state disattivate dai loro sviluppatori per essere analizzati e strumentati e non vengono distribuiti utenti finali. Il Google Play Store non consente la distribuzione di app. In questo modo si garantisce che le app normali (inclusi i componenti principali) non possano instrumentati o manipolati.
Design
Il flusso generale e l'interconnessione in un'app instrumentata sono mostrati in Figura 1.
.
Il plug-in ART libopenjdkjvmti
espone ART TI, che è
progettata per soddisfare le esigenze e i vincoli della piattaforma:
- La ridefinizione del corso si basa su file
Dex
, contenenti solo una definizione singola di classe, anziché file di classe. - Le API in linguaggio Java per la strumentazione e la ridefinizione non sono esposte.
ART TI supporta anche i profiler di Android Studio.
Carica o collega un agente
Per collegare un agente all'avvio del runtime, utilizza questo comando per caricare sia Plug-in JVMTI e agente specificato:
dalvikvm -Xplugin:libopenjdkjvmti.so -agentpath:/path/to/agent/libagent.so …
Non vengono applicate misure di sicurezza quando un agente viene caricato in fase di runtime quindi tieni presente che un runtime avviato manualmente consente modifiche senza l'applicazione di misure di sicurezza. (In questo modo è possibile eseguire test ART).
Nota: questa opzione non si applica alle app normali (incluso il sistema server) su un dispositivo. Le app vengono create con fork da uno zigote già in esecuzione e un processo zigote non è autorizzato a caricare gli agenti.
Per collegare un agente a un'app già in esecuzione, utilizza questo :
adb shell cmd activity attach-agent [process] /path/to/agent/libagent.so[=agent-options]
Se il plug-in JVMTI non è stato ancora caricato, il collegamento di un agente carica entrambi il plug-in e la libreria degli agenti.
Un agente può essere collegato solo a un'app in esecuzione contrassegnata come
debuggable (parte del manifest dell'app, con attributo
android:debuggable
impostata su true
nell'app
). Sia la classe ActivityManager
che la ART si esibiscono
dei controlli prima di consentire il collegamento di un agente. ActivityManager
verifica le informazioni attuali dell'app (ricavate da PackageManager)
dei dati della classe) per lo stato di cui è possibile eseguire il debug e il runtime ne controlla lo stato attuale,
che è stato impostato
all'avvio dell'app.
Località degli agenti
Il runtime deve caricare gli agenti nel processo attuale, in modo che
possono associarsi e comunicare direttamente con quest'ultimo. La stessa ART è agnostica
in merito alla località specifica da cui proviene l'agente. La stringa viene utilizzata
per una chiamata dlopen
. Autorizzazioni del file system e criteri SELinux
per limitare il caricamento effettivo.
Per pubblicare gli agenti che possono essere eseguiti da un'app di cui è possibile eseguire il debug, segui questi passaggi:
- Incorpora l'agente nella directory della libreria dell'APK dell'app.
- Usa
run-as
per copiare l'agente nei dati dell'app .
API
Il seguente metodo è stato aggiunto a 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 {
Altre API Android
Il comando attach-agent è visibile pubblicamente. Questo comando collega un token JVMTI a un processo in esecuzione:
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;\''
I comandi am start -P
e am
start-profiler/stop-profiler
sono simili al comando attach-agent.
JVMTI
Questa funzionalità espone l'API JVMTI agli agenti (codice nativo). L'importante includono:
- Ridefinire una classe.
- Monitoraggio dell'allocazione degli oggetti e della garbage collection.
- Esegui l'iterazione su tutti gli oggetti di un heap, seguendo l'albero di riferimento delle di oggetti strutturati.
- Ispezione degli stack di chiamate Java.
- Sospendere (e riprendere) tutti i thread.
Potrebbero essere disponibili funzionalità diverse su versioni diverse di Android.
Compatibilità
Questa funzionalità richiede il supporto principale del runtime, disponibile solo su Android 8.0 e superiori. I produttori di dispositivi non devono apportare alcuna modifica per l'implementazione questa funzionalità. Fa parte di AOSP.
Convalida
CTS esegue i seguenti test su Android 8 e versioni successive:
- Verifica che gli agenti si colleghino alle app di cui è possibile eseguire il debug e non si collegano alle app e non di cui non è possibile eseguire il debug.
- Testa tutte le API JVMTI implementate
- Verifica che l'interfaccia binaria per gli agenti sia stabile
Ad Android 9 e versioni successive sono stati aggiunti ulteriori test che sono inclusi nei test CTS per queste release.