Android NDK поддерживает HWAddress Sanitizer , также известный как HWASan, начиная с NDK r21 и Android 10 (уровень API 29). HWASan доступен только на 64-битных устройствах Arm.
HWASan — это инструмент обнаружения ошибок памяти, аналогичный ASan. По сравнению с классическим ASan, HWASan обладает следующими преимуществами:
- Аналогичная загрузка ЦП (~2x)
- Аналогичные накладные расходы по размеру кода (40–50%)
- Значительно меньшие накладные расходы на ОЗУ (10% – 35%)
HWASan обнаруживает тот же набор ошибок, что и ASan:
- Переполнение или опустошение буфера стека и кучи
- Использование кучи после освобождения
- Использование стека вне области действия
- Двойной бесплатный или дикий бесплатный
Кроме того, HWASan также обнаруживает:
- Использование стека после возврата
Пример приложения
Пример приложения показывает, как настроить вариант сборки для hwasan.
Строить
Чтобы создать собственный код вашего приложения (JNI) с помощью HWAddress Sanitizer , выполните следующие действия:
ndk-build
В вашем файле Application.mk
:
APP_STL := c++_shared # Or system, or none, but not c++_static.
APP_CFLAGS := -fsanitize=hwaddress -fno-omit-frame-pointer
APP_LDFLAGS := -fsanitize=hwaddress
CMake (Gradle Groovy)
В файле build.gradle
вашего модуля:
android {
defaultConfig {
externalNativeBuild {
cmake {
# Can also use system or none as ANDROID_STL, but not c++_static.
arguments "-DANDROID_STL=c++_shared"
}
}
}
}
Для каждой цели в вашем CMakeLists.txt:
target_compile_options(${TARGET} PUBLIC -fsanitize=hwaddress -fno-omit-frame-pointer)
target_link_options(${TARGET} PUBLIC -fsanitize=hwaddress)
С NDK 27 или более новой версией вы также можете использовать следующее в вашем build.gradle
и не придется изменять CMakeLists.txt:
android {
defaultConfig {
externalNativeBuild {
cmake {
arguments "-DANDROID_SANITIZE=hwaddress"
}
}
}
}
Это не будет работать при использовании ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false
.
CMake (Gradle Kotlin)
В файле build.gradle
вашего модуля:
android {
defaultConfig {
externalNativeBuild {
cmake {
# Can also use system or none as ANDROID_STL, but not c++_static.
arguments += "-DANDROID_STL=c++_shared"
}
}
}
}
Для каждой цели в вашем CMakeLists.txt:
target_compile_options(${TARGET} PUBLIC -fsanitize=hwaddress -fno-omit-frame-pointer)
target_link_options(${TARGET} PUBLIC -fsanitize=hwaddress)
С NDK 27 или более новой версией вы также можете использовать следующее в вашем build.gradle
и не придется изменять CMakeLists.txt:
android {
defaultConfig {
externalNativeBuild {
cmake {
arguments += "-DANDROID_SANITIZE=hwaddress"
}
}
}
}
Это не будет работать при использовании ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false
.
Android 14 или новее: добавьте wrap.sh
Если вы используете Android 14 или более позднюю версию, вы можете использовать скрипт wrap.sh для запуска отлаживаемого приложения на любом устройстве Android. Этот шаг можно пропустить, если вы решили следовать инструкциям по настройке .
Следуйте инструкциям по упаковке скрипта wrap.sh, чтобы добавить следующий скрипт wrap.sh для arm64-v8a
.
#!/system/bin/sh
LD_HWASAN=1 exec "$@"
Бегать
Если вы используете версию Android ниже 14 или не добавили скрипт wrap.sh, следуйте инструкциям по настройке перед запуском приложения.
Запустите приложение как обычно. При обнаружении ошибки памяти приложение аварийно завершает работу с сигналом SIGABRT и выводит подробное сообщение в logcat. Копию сообщения можно найти в файле в каталоге /data/tombstones
Она выглядит следующим образом:
ERROR: HWAddressSanitizer: tag-mismatch on address 0x0042a0826510 at pc 0x007b24d90a0c
WRITE of size 1 at 0x0042a0826510 tags: 32/3d (ptr/mem) in thread T0
#0 0x7b24d90a08 (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x2a08)
#1 0x7b8f1e4ccc (/apex/com.android.art/lib64/libart.so+0x198ccc)
#2 0x7b8f1db364 (/apex/com.android.art/lib64/libart.so+0x18f364)
#3 0x7b8f2ad8d4 (/apex/com.android.art/lib64/libart.so+0x2618d4)
0x0042a0826510 is located 0 bytes to the right of 16-byte region [0x0042a0826500,0x0042a0826510)
allocated here:
#0 0x7b92a322bc (/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so+0x212bc)
#1 0x7b24d909e0 (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x29e0)
#2 0x7b8f1e4ccc (/apex/com.android.art/lib64/libart.so+0x198ccc)
За сообщением может следовать дополнительная отладочная информация, включая список активных потоков в приложении, теги соседних выделений памяти и значения регистров ЦП.
Дополнительную информацию об ошибках HWASan см. в разделе «Понимание отчетов HWASan» .
Создание исполняемых файлов командной строки
Вы можете собирать и запускать исполняемые файлы, инструментированные HWASan, на Android 14 и более поздних версиях. Для ваших исполняемых файлов можно использовать ту же конфигурацию, что описана в разделе Сборка для ndk-build или CMake. Загрузите исполняемые файлы на устройство под управлением Android 14 или более поздней версии и запустите их как обычно, используя оболочку.
Если вы используете libc++, убедитесь, что вы используете общую STL, поместите ее на устройство и установите LD_LIBRARY_PATH
на каталог, содержащий ее, при запуске вашего двоичного файла.
Если вы не используете Gradle, ознакомьтесь с документацией NDK, чтобы узнать, как выполнить сборку из командной строки с помощью CMake и ndk-build .
Android 13 или более ранняя версия: настройка
Если ваше устройство работает под управлением Android 14 или более поздней версии, вы можете пропустить этот шаг и следовать инструкциям по использованию wrap.sh в разделе «Сборка» . Вы также можете следовать этому разделу и пропустить инструкции по использованию wrap.sh.
До Android 14 для работы приложений HWASan требовалась сборка Android HWASan. Вы можете прошивать готовые образы HWASan на поддерживаемые устройства Pixel. Сборки доступны на сайте ci.android.com , где можно нажать на квадратик нужной сборки, чтобы получить ссылку на Flash-сборку . Для этого необходимо знать кодовое имя вашего телефона .
Возможно, проще перейти сразу на flash.android.com, поскольку там процесс начинается с определения вашего устройства и отображаются только те сборки, которые вы можете использовать. На следующих изображениях показан процесс настройки в этом инструменте.
Включите режим разработчика на устройстве и подключите его к компьютеру с помощью USB-кабеля. Нажмите « Добавить новое устройство» , выберите устройство в диалоговом окне и нажмите «Подключить» .
После подключения устройства нажмите на него, чтобы настроить сборку. В поле «Выберите идентификатор сборки» выберите ветку aosp-master-with-phones-throttled
чтобы автоматически выбрать нужный образ для подключенного устройства.
Нажмите «Установить» , чтобы прошить устройство.
Более подробную информацию о необходимой настройке можно найти в документации Android Flash Tool . Кроме того, вы можете обратиться к документации AOSP за инструкциями по сборке образа HWASan из исходного кода.