Обернуть сценарий оболочки

При отладке и профилировании приложений с использованием собственного кода часто бывает полезно использовать инструменты отладки, которые необходимо включать при запуске процесса. Для этого необходимо запустить приложение в новом процессе, а не клонировать из зиготы. Примеры включают в себя:

Используйте сценарий оболочки оболочки

Использовать wrap.sh очень просто:

  1. Скомпилируйте собственный отлаживаемый APK, который содержит следующее:
    • Сценарий оболочки с именем wrap.sh Дополнительные сведения см. в разделах Создание сценария оболочки оболочки и Пакет Wrap.sh.
    • Любые дополнительные инструменты, необходимые вашему сценарию оболочки (например, ваш собственный двоичный файл strace ).
  2. Установите отлаживаемый APK на устройство.
  3. Запустите приложение.

Создайте сценарий оболочки оболочки

Когда вы запускаете отлаживаемый APK-файл, содержащий wrap.sh , система выполняет сценарий и передает команду для запуска приложения в качестве аргументов. Скрипт отвечает за запуск приложения, но может вносить любые изменения в среду или аргументы. Сценарий должен следовать синтаксису оболочки MirBSD Korn (mksh).

В следующем фрагменте показано, как написать простой файл wrap.sh , который просто запускает приложение:

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

Отладка Malloc

Чтобы использовать отладку malloc через wrap.sh , вы должны включить следующую строку:

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

Асан

В документации ASan есть пример того, как это сделать для ASan.

Пакет Wrap.sh

Чтобы воспользоваться преимуществами wrap.sh , ваш APK должен поддерживать отладку. Убедитесь, что параметр android:debuggable="true" настроен в элементе <application> манифеста Android, или, если вы используете Android Studio, вы настроили отладочную сборку в файле build.gradle .

Также необходимо установить useLegacyPackaging значение true в файле build.gradle вашего приложения. В большинстве случаев для этой опции по умолчанию установлено значение false , поэтому вы можете явно установить для нее значение true , чтобы избежать каких-либо неожиданностей.

Вы должны упаковать сценарий wrap.sh с собственными библиотеками приложения. Если ваше приложение не содержит собственных библиотек, добавьте каталог lib вручную в каталог вашего проекта. Для каждой архитектуры, которую поддерживает ваше приложение, вы должны предоставить копию сценария оболочки оболочки в каталоге собственной библиотеки.

В следующем примере показан макет файла для поддержки архитектур ARMv8 и x86-64:

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

Android Studio упаковывает файлы .so только из каталогов lib/ , поэтому, если вы являетесь пользователем Android Studio, вам нужно вместо этого поместить файлы wrap.sh в каталоги src/main/resources/lib/* , чтобы они будут упакованы правильно.

Обратите внимание, что resources/lib/x86 будет отображаться в пользовательском интерфейсе как lib.x86 , но на самом деле это должен быть подкаталог:

Пример упаковки Wrap.sh в Android Studio

Отладка при использовании Wrap.sh

Если вы хотите подключить отладчик при использовании wrap.sh , ваш сценарий оболочки должен будет вручную включить отладку. Как это сделать, в разных выпусках различается, поэтому в этом примере показано, как добавить соответствующие параметры для всех выпусков, поддерживающих 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