В Android 8.0 и более поздних версиях интерфейс ART Tooling Interface (ART TI) предоставляет доступ к некоторым внутренним компонентам среды выполнения и позволяет профилировщикам и отладчикам влиять на поведение приложений во время выполнения. Это позволяет использовать современные инструменты повышения производительности, которые предоставляются для реализации нативных агентов на других платформах.
Внутренние компоненты среды выполнения доступны агентам, загруженным в процесс среды выполнения.
Они взаимодействуют с ART с помощью прямых вызовов и обратных вызовов. Среда выполнения поддерживает несколько агентов, чтобы можно было разделить различные задачи профилирования. Агенты могут быть предоставлены при запуске (когда вызываются dalvikvm или app_process) или прикреплены к уже запущенному процессу.
Поскольку возможность настраивать и изменять поведение приложения и среды выполнения очень эффективна, в ART TI были интегрированы две меры безопасности:
- Во-первых, код, предоставляющий интерфейс агента, JVMTI, реализован как плагин среды выполнения, а не как основной компонент среды выполнения. Загрузка плагинов может быть ограничена, чтобы агенты не могли найти ни одну из точек интерфейса.
- Во-вторых, класс
ActivityManagerи процесс среды выполнения разрешают агентам подключаться только к отлаживаемым приложениям. Приложения, доступные для отладки, подписаны разработчиками для анализа и инструментирования и не распространяются среди конечных пользователей. В Google Play запрещено распространять приложения, доступные для отладки. Это гарантирует, что обычные приложения (включая основные компоненты) нельзя будет отслеживать или изменять.
Дизайн
Общая схема работы и взаимосвязи в инструментированном приложении показаны на рисунке 1.
Плагин ART libopenjdkjvmti предоставляет доступ к интерфейсу ART TI, который разработан с учетом потребностей и ограничений платформы:
- Переопределение класса выполняется на основе файлов
Dex, содержащих только одно определение класса, а не файлов классов. - API на языке Java для инструментирования и переопределения не предоставляются.
ART TI также поддерживает профилировщики Android Studio.
Загрузить или прикрепить агента
Чтобы подключить агента при запуске среды выполнения, используйте следующую команду для загрузки плагина JVMTI и указанного агента:
dalvikvm -Xplugin:libopenjdkjvmti.so -agentpath:/path/to/agent/libagent.so …
При загрузке агента во время запуска среды выполнения меры безопасности не применяются, поэтому помните, что при запуске среды выполнения вручную можно вносить любые изменения без ограничений. (Это позволяет тестировать ART.)
Примечание. Это неприменимо к обычным приложениям (в том числе к системному серверу) на устройстве. Приложения ответвляются от уже запущенного процесса zygote, а ему не разрешено загружать агентов.
Чтобы подключить агента к уже запущенному приложению, используйте следующую команду:
adb shell cmd activity attach-agent [process] /path/to/agent/libagent.so[=agent-options]
Если плагин JVMTI ещё не загружен, при подключении агента загружаются и плагин, и библиотека агента.
Агент можно подключить только к запущенному приложению, которое отмечено как доступное для отладки (часть манифеста приложения с атрибутом android:debuggable, для которого в узле приложения задано значение true). Класс ActivityManager и ART выполняют проверки, прежде чем разрешить подключение агента. Класс ActivityManager проверяет текущую информацию о приложении (полученную из данных класса PackageManager) на наличие статуса отладки, а среда выполнения проверяет текущий статус, который был задан при запуске приложения.
Местоположения агентов
Среда выполнения должна загрузить агентов в текущий процесс, чтобы агент мог напрямую связаться с ней и взаимодействовать. Сама ART не зависит от того, из какого местоположения поступает запрос. Строка используется для вызова dlopen. Разрешения файловой системы и правила SELinux ограничивают фактическую загрузку.
Чтобы предоставить агентов, которые могут быть запущены отлаживаемым приложением, выполните следующие действия:
- Встройте агент в каталог библиотеки APK-файла приложения.
- Используйте
run-as, чтобы скопировать агента в каталог данных приложения.
API
В 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
Команда attach-agent видна всем. Эта команда подключает агент JVMTI к запущенному процессу:
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;\''
Команды am start -P и am
start-profiler/stop-profiler похожи на команду attach-agent.
JVMTI
Эта функция предоставляет агентам (нативному коду) доступ к JVMTI API. К важным возможностям относятся:
- Переопределение класса.
- Отслеживание выделения объектов и сборки мусора.
- Перебор всех объектов в куче по дереву ссылок.
- Проверка стеков вызовов Java.
- приостанавливать и возобновлять все потоки;
На разных версиях Android могут быть доступны разные функции.
Совместимость
Для работы этой функции требуется поддержка среды выполнения, которая доступна только в Android 8.0 и более поздних версиях. Производителям устройств не нужно вносить никаких изменений, чтобы реализовать эту функцию. Он входит в состав AOSP.
Проверка
В Android 8 и более поздних версиях CTS проверяет следующее:
- Тесты, которые агенты подключают к приложениям с возможностью отладки, но не могут подключить к приложениям без такой возможности.
- Тестирует все реализованные API JVMTI.
- Тесты стабильности двоичного интерфейса для агентов
В Android 9 и более поздних версиях добавлены дополнительные тесты, которые включены в набор CTS для этих версий.