При отладке и профилировании приложений с использованием собственного кода часто бывает полезно использовать инструменты отладки, которые необходимо включать при запуске процесса. Для этого необходимо запустить приложение в новом процессе, а не клонировать из зиготы. Примеры включают в себя:
- Отслеживание системных вызовов с помощью strace .
- Поиск ошибок памяти с помощью отладки malloc или Address Sanitizer (ASan) .
- Профилирование с помощью Simpleperf .
Используйте сценарий оболочки оболочки
Использовать wrap.sh очень просто:
- Скомпилируйте собственный отлаживаемый APK, который содержит следующее:
- Сценарий оболочки с именем
wrap.shДополнительные сведения см. в разделах Создание сценария оболочки оболочки и Пакет Wrap.sh. - Любые дополнительные инструменты, необходимые вашему сценарию оболочки (например, ваш собственный двоичный файл
strace).
- Сценарий оболочки с именем
- Установите отлаживаемый APK на устройство.
- Запустите приложение.
Создайте сценарий оболочки оболочки
Когда вы запускаете отлаживаемый 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
Если вы хотите подключить отладчик при использовании 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