Skrypt powłoki pakuj

Do debugowania i profilowania aplikacji za pomocą kodu natywnego często warto użyć narzędzi do debugowania, które trzeba włączyć przy uruchamianiu procesu. Wymaga to uruchomienia aplikacji w nowym procesie, a nie jej klonowania z zygoty. Przykłady:

Używanie skryptu powłoki zawijania

Korzystanie z wrap.sh jest łatwe:

  1. Skompiluj niestandardowy plik APK z możliwością debugowania, który zawiera następujące pakiety:
  2. Zainstaluj na urządzeniu plik APK możliwy do debugowania.
  3. Uruchom aplikację.

Tworzenie skryptu powłoki opakowującej

Gdy uruchomisz pakiet APK z możliwością debugowania, który zawiera wrap.sh, system uruchomi skrypt i przekaże polecenie uruchomienia aplikacji jako argumenty. Skrypt odpowiada za uruchomienie aplikacji, ale może wprowadzać dowolne zmiany w środowisku lub argumentach. Skrypt powinien być zgodny ze składnią powłoki MirBSD Korn (mksh).

Ten fragment kodu pokazuje, jak napisać prosty plik wrap.sh, który powoduje uruchomienie aplikacji:

#!/system/bin/sh
exec "$@"

Debugowanie Malloca

Aby użyć debugowania malloc za pomocą wrap.sh, musisz dodać ten wiersz:

#!/system/bin/sh
LIBC_DEBUG_MALLOC_OPTIONS=backtrace logwrapper "$@"

ASan

Przykład znajdziesz w dokumentacji ASan.

Opakowywanie wrap.sh

Aby można było skorzystać z funkcji wrap.sh, plik APK musi być możliwy do debugowania. Upewnij się, że ustawienie android:debuggable="true" jest skonfigurowane w elemencie <application> w pliku manifestu Androida lub jeśli w Android Studio masz skonfigurowaną kompilację debugowania w pliku build.gradle.

Musisz też ustawić useLegacyPackaging na true w pliku build.gradle aplikacji. W większości przypadków ta opcja ma domyślną wartość false, dlatego warto ustawić ją bezpośrednio na true, aby uniknąć niespodzianek.

Musisz spakować skrypt wrap.sh z natywnymi bibliotekami aplikacji. Jeśli Twoja aplikacja nie zawiera bibliotek natywnych, dodaj ręcznie katalog lib do katalogu projektu. W przypadku każdej architektury obsługiwanej przez Twoją aplikację musisz udostępnić kopię skryptu powłoki zawijania w katalogu biblioteki natywnej.

Poniższy przykład przedstawia układ pliku zapewniający obsługę architektur ARMv8 i x86-64:

# App Directory
|- AndroidManifest.xml
|- …
|- lib
   |- arm64-v8a
      |- ...
      |- wrap.sh
   |- x86_64
      |- ...
      |- wrap.sh

Android Studio pakuje tylko pliki .so z katalogów lib/. Jeśli korzystasz z Androida Studio, pliki wrap.sh musisz umieścić w katalogach src/main/resources/lib/*, by zostały poprawnie spakowane.

Uwaga: adres resources/lib/x86 będzie wyświetlany w interfejsie jako lib.x86, ale w rzeczywistości powinien to być podkatalog:

Przykład opakowania wrap.sh w Android Studio

Debuguj przy użyciu wrap.sh

Jeśli chcesz podłączyć debuger, gdy używasz wrap.sh, musisz ręcznie włączyć debugowanie za pomocą skryptu powłoki. Różnią się sposoby wykonywania tych czynności w poszczególnych wersjach, więc w tym przykładzie pokazujemy, jak dodawać odpowiednie opcje dla wszystkich wersji obsługujących wrap.sh:

#!/system/bin/sh

cmd=$1
shift

os_version=$(getprop ro.build.version.sdk)

if [ "$os_version" -eq "27" ]; then
  cmd="$cmd -Xrunjdwp:transport=dt_android_adb,suspend=n,server=y -Xcompiler-option --debuggable $@"
elif [ "$os_version" -eq "28" ]; then
  cmd="$cmd -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y -Xcompiler-option --debuggable $@"
else
  cmd="$cmd -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y $@"
fi

exec $cmd