SZTUKA TI

W systemie Android 8.0 i nowszych interfejs ART Tooling Interface (ART TI) udostępnia pewne elementy wewnętrzne środowiska wykonawczego i umożliwia profilerom i debugerom wpływanie na zachowanie aplikacji w czasie wykonywania. Można to wykorzystać do wdrożenia najnowocześniejszych narzędzi wydajnościowych udostępnianych do wdrażania agentów natywnych na innych platformach.

Elementy wewnętrzne środowiska wykonawczego są udostępniane agentom załadowanym do procesu wykonawczego. Komunikują się one z ART poprzez bezpośrednie połączenia i oddzwonienia. Środowisko wykonawcze obsługuje wielu agentów, dzięki czemu można oddzielić różne problemy związane z profilowaniem ortogonalnym. Agenci mogą być dostarczani na początku działania (kiedy wywoływane są dalvikvm lub app_process ) lub dołączani do już działającego procesu.

Ponieważ możliwość instrumentowania i modyfikowania zachowania aplikacji i środowiska wykonawczego jest bardzo potężna, w ART TI zintegrowano dwa środki bezpieczeństwa:

  • Po pierwsze, kod udostępniający interfejs agenta, JVMTI, jest zaimplementowany jako wtyczka środowiska wykonawczego, a nie podstawowy komponent środowiska wykonawczego. Ładowanie wtyczek może zostać ograniczone, tak aby agenci nie mogli znaleźć żadnego z punktów interfejsu.
  • Po drugie, zarówno klasa ActivityManager , jak i proces wykonawczy pozwalają agentom łączyć się tylko z aplikacjami, które można debugować. Aplikacje z możliwością debugowania zostały zatwierdzone przez ich programistów w celu analizy i instrumentacji i nie są dystrybuowane do użytkowników końcowych. Sklep Google Play nie pozwala na dystrybucję aplikacji, które można debugować. Dzięki temu nie można instrumentować ani manipulować zwykłymi aplikacjami (w tym podstawowymi komponentami).

Projekt

Ogólny przepływ i wzajemne połączenia w oprzyrządowanej aplikacji pokazano na rysunku 1 .

Flow and interconnection in an instrumented app
Rysunek 1. Przepływ i wzajemne połączenia aplikacji instrumentalnej

Wtyczka ART libopenjdkjvmti udostępnia ART TI, który został zaprojektowany tak, aby dostosować się do potrzeb i ograniczeń platformy:

  • Redefinicja klasy opiera się na plikach Dex , zawierających tylko jedną definicję klasy, zamiast plików klas.
  • Interfejsy API w języku Java służące do instrumentacji i redefinicji nie są ujawniane.

ART TI obsługuje także profilery Android Studio.

Załaduj lub podłącz agenta

Aby dołączyć agenta podczas uruchamiania środowiska wykonawczego, użyj tej komendy, aby załadować zarówno wtyczkę JVMTI, jak i danego agenta:

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

Nie obowiązują żadne środki bezpieczeństwa w przypadku ładowania agenta podczas uruchamiania środowiska wykonawczego, należy więc pamiętać, że ręcznie uruchomione środowisko wykonawcze umożliwia pełną modyfikację bez stosowania środków bezpieczeństwa. (Pozwala to na testowanie ART.)

Uwaga: nie dotyczy to zwykłych aplikacji (w tym serwera systemowego) na urządzeniu. Aplikacje są tworzone z już działającej zygoty, a proces zygoty nie może ładować agentów.

Aby dołączyć agenta do już uruchomionej aplikacji, użyj tego polecenia:

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

Jeśli wtyczka JVMTI nie została jeszcze załadowana, dołączenie agenta powoduje załadowanie zarówno wtyczki, jak i biblioteki agenta.

Agent może być podłączony tylko do działającej aplikacji, która jest oznaczona jako możliwa do debugowania (część manifestu aplikacji z atrybutem android:debuggable ustawionym na true w węźle aplikacji). Zarówno klasa ActivityManager , jak i ART przeprowadzają kontrole przed zezwoleniem na dołączenie agenta. Klasa ActivityManager sprawdza bieżące informacje o aplikacji (pochodzące z danych klasy PackageManager ) pod kątem statusu możliwego do debugowania, a środowisko wykonawcze sprawdza jej bieżący stan, który został ustawiony podczas uruchamiania aplikacji.

Lokalizacje agentów

Środowisko wykonawcze musi załadować agenty do bieżącego procesu, aby agent mógł bezpośrednio się z nim powiązać i komunikować się z nim. Sam ART jest agnostykiem w odniesieniu do konkretnego miejsca, z którego pochodzi agent. Ciąg ten jest używany do wywołania dlopen . Uprawnienia systemu plików i zasady SELinux ograniczają faktyczne ładowanie.

Aby dostarczyć agenty, które można uruchomić za pomocą aplikacji, którą można debugować, wykonaj następujące czynności:

  • Osadź agenta w katalogu bibliotek pakietu APK aplikacji.
  • Użyj funkcji run-as , aby skopiować agenta do katalogu danych aplikacji.

Pszczoła

Następująca metoda została dodana do 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 {

Inne interfejsy API Androida

Polecenie connect-agent jest widoczne publicznie. To polecenie dołącza agenta JVMTI do działającego procesu:

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

Polecenia am start -P i am start-profiler/stop-profiler są podobne do polecenia connect-agent.

JVMTI

Ta funkcja udostępnia agentom interfejs API JVMTI (kod natywny). Do ważnych możliwości należą:

  • Nowa definicja klasy.
  • Śledzenie alokacji obiektów i zbierania śmieci.
  • Iteracja po wszystkich obiektach na stercie, zgodnie z drzewem referencyjnym obiektów.
  • Sprawdzanie stosów wywołań Java.
  • Zawieszanie (i wznawianie) wszystkich wątków.

W różnych wersjach Androida mogą być dostępne różne możliwości.

Zgodność

Ta funkcja wymaga podstawowej obsługi środowiska wykonawczego, która jest dostępna tylko w systemie Android 8.0 i nowszych wersjach. Producenci urządzeń nie muszą wprowadzać żadnych zmian, aby wdrożyć tę funkcję. Jest częścią AOSP.

Walidacja

CTS testuje następujące elementy na Androidzie 8 i nowszych:

  • Testy, które agenci dołączają do aplikacji możliwych do debugowania i nie łączą się z aplikacjami, których nie można debugować.
  • Testuje wszystkie zaimplementowane interfejsy API JVMTI
  • Testuje, czy interfejs binarny agentów jest stabilny

Do Androida 9 i nowszych wersji dodano dodatkowe testy, które są uwzględnione w testach CTS tych wydań.