В Android 8.0 и более поздних версиях интерфейс инструментов ART (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 …
При загрузке агента при запуске среды выполнения не принимаются меры безопасности, поэтому имейте в виду, что среда выполнения, запускаемая вручную, допускает полную модификацию без принятия мер безопасности. (Это позволяет проводить АРТ-тестирование.)
Примечание. Это неприменимо к обычным приложениям (включая системный сервер) на устройстве. Приложения созданы из уже работающей зиготы, и процессу зиготы не разрешено загружать агенты.
Чтобы прикрепить агент к уже запущенному приложению, используйте следующую команду:
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
Эта функция предоставляет агентам API JVMTI (собственный код). К важным возможностям относятся:
- Переопределение класса.
- Отслеживание выделения объектов и сборка мусора.
- Перебор всех объектов в куче, следуя дереву ссылок объектов.
- Проверка стеков вызовов Java.
- Приостановка (и возобновление) всех потоков.
В разных версиях Android могут быть доступны разные возможности.
Совместимость
Для этой функции требуется базовая поддержка среды выполнения, доступная только на Android 8.0 и более поздних версиях. Производителям устройств не нужно вносить какие-либо изменения для реализации этой функции. Это часть AOSP.
Валидация
CTS тестирует следующее на Android 8 и выше:
- Тесты, которые агенты прикрепляют к отлаживаемым приложениям и не прикрепляют к неотлаживаемым приложениям.
- Тестирует все реализованные API JVMTI.
- Проверяет стабильность двоичного интерфейса агентов.
Дополнительные тесты были добавлены в Android 9 и более поздних версий и включены в тесты CTS для этих выпусков.