ART TI

Dans Android 8.0 et versions ultérieures, ART Tooling Interface (ART TI) expose certains composants internes de l'environnement d'exécution, et permet aux profileurs et débogueurs d'influencer le comportement d'exécution des applications. Cela permet d'implémenter outils de performance de pointe fournis pour implémenter des agents natifs sur d'autres plates-formes.

Les composants internes de l'environnement d'exécution sont exposés aux agents qui ont été chargés dans le processus d'exécution. Elles communiquent avec l'ART via des appels directs et des rappels. L'environnement d'exécution prend en charge plusieurs agents, ce qui permet de résoudre les problèmes de profilage être séparés. Les agents peuvent être fournis au démarrage de l'exécution (lorsque dalvikvm ou app_process sont appelés), ou associés à un processus déjà en cours d'exécution.

Parce que la possibilité d'instrumenter et de modifier le comportement de l'application et de l'environnement d'exécution est très puissant, deux mesures de sécurité ont été intégrées à ART TI:

  • Tout d'abord, le code exposant l'interface de l'agent, JVMTI, est implémenté et non un composant essentiel de l'environnement d'exécution. Le chargement du plug-in peut être de sorte que les agents ne puissent pas trouver l'interface points.
  • Deuxièmement, la classe ActivityManager et le processus d'exécution ne permettent aux agents joindre aux applications débogables. Les applications débogables ont été approuvées par leurs développeurs doivent être analysées et instrumentées, et ne sont pas distribuées les utilisateurs finaux. Le Google Play Store n'autorise pas la distribution d'éléments débogables applications. Ainsi, les applications standards (y compris les composants de base) ne peuvent pas instrumentées ou manipulées.

Conception

Le flux général et l'interconnexion dans une application instrumentée sont représentés dans Figure 1 :

Flux et interconnexion dans une application instrumentée
Figure 1 : Flux et interconnexion d'une application instrumentée

Le plug-in ART libopenjdkjvmti expose ART TI, qui est conçue pour répondre aux besoins et aux contraintes de la plate-forme:

  • La redéfinition des classes s'appuie sur les fichiers Dex, qui ne contiennent qu'un une définition de classe unique, au lieu de fichiers de classe.
  • Les API en langage Java pour l'instrumentation et la redéfinition exposées.

ART TI est également compatible avec les profileurs Android Studio.

Charger ou associer un agent

Pour associer un agent au démarrage de l'environnement d'exécution, utilisez cette commande pour charger à la fois Plug-in JVMTI et agent donné:

dalvikvm -Xplugin:libopenjdkjvmti.so -agentpath:/path/to/agent/libagent.so …

Aucune mesure de sécurité n'est mise en place lorsqu'un agent est chargé au moment de l'exécution n'oubliez pas qu'un environnement d'exécution démarré manuellement permet d'exécuter sans mesures de sécurité. (cela permet d'effectuer des tests ART).

Remarque: cela ne s'applique pas aux applications standards (y compris les applications serveur) sur un appareil. Les applications sont issues d'un zygote déjà en cours d'exécution, et qu'un processus zygote n'est pas autorisé à charger des agents.

Pour associer un agent à une application en cours d'exécution, utilisez cette :

adb shell cmd activity attach-agent [process]
/path/to/agent/libagent.so[=agent-options]

Si le plug-in JVMTI n'a pas encore été chargé, l'association d'un agent permet de charger les deux le plug-in et la bibliothèque de l'agent.

Un agent ne peut être associé qu'à une application en cours d'exécution marquée comme debuggable (élément du fichier manifeste de l'application, avec l'attribut android:debuggable défini sur true dans l'application du nœud). La classe ActivityManager et l'ART fonctionnent avant d'autoriser l'association d'un agent. ActivityManager vérifie les informations actuelles sur l'application (issues de PackageManager les données de classe) pour l'état débogable, et l'environnement d'exécution vérifie son état actuel. défini au démarrage de l'application.

Emplacements des agents

L'environnement d'exécution doit charger des agents dans le processus en cours, afin que l'agent peut s'y lier directement et communiquer avec elle. L'ART lui-même est indépendante concernant l'emplacement spécifique d'où provient l'agent. La chaîne est utilisée pour un appel dlopen. Autorisations du système de fichiers et règles SELinux pour limiter le chargement réel.

Pour fournir des agents pouvant être exécutés par une application débogable, procédez comme suit:

  • Intégrez l'agent dans le répertoire de bibliothèque de l'APK de l'application.
  • Utiliser run-as pour copier l'agent dans les données de l'application .

API

La méthode suivante a été ajoutée à 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 {

Autres API Android

La commande attach-agent est visible publiquement. Cette commande associe un objet JVMTI à un processus en cours d'exécution:

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;\''

Les commandes am start -P et am start-profiler/stop-profiler sont semblables à la commande attach-agent.

JVMTI

Cette fonctionnalité expose l'API JVMTI aux agents (code natif). L'important notamment:

  • Redéfinir une classe
  • Suivi de l'allocation d'objets et de la récupération de mémoire
  • Itérer sur tous les objets d'un tas de mémoire en suivant l'arborescence de référence d'objets.
  • Inspecter les piles d'appels Java
  • Suspension (et réactivation) de tous les threads.

Différentes fonctionnalités peuvent être disponibles selon les versions Android

Compatibilité

Cette fonctionnalité nécessite une prise en charge des environnements d'exécution de base, uniquement disponible sur Android 8.0 et supérieurs. Les fabricants d'appareils n'ont aucune modification à apporter pour implémenter cette fonctionnalité. Il fait partie d'AOSP.

Validation

CTS teste les éléments suivants sur Android 8 ou version ultérieure:

  • Tests que les agents associent à des applications débogables et qui échouent les applications non débogables.
  • Teste toutes les API JVMTI implémentées
  • Vérifie que l'interface binaire des agents est stable

Des tests supplémentaires ont été ajoutés à Android 9 et versions ultérieures et sont inclus lors des tests CTS de ces versions.