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 или более поздней версии, то можете запустить отладочное приложение на любом устройстве Android с помощью скрипта wrap.sh. Если вы выполнили инструкции из руководства по настройке, этот шаг можно пропустить.
Следуйте инструкциям по упаковке скрипта 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, на устройствах с 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 требовалась сборка HWASan Android. Вы можете установить готовые образы HWASan на поддерживаемые устройства Pixel. Сборки доступны на сайте ci.android.com. Чтобы получить ссылку на Flash Build, нажмите на квадрат нужной сборки. Для этого вам нужно знать кодовое название своего телефона.
Возможно, вам будет проще перейти сразу на сайт flash.android.com, поскольку там процесс начинается с обнаружения вашего устройства и вам показываются только те сборки, которые можно использовать. На изображениях ниже показан процесс настройки в этом инструменте.
Включите режим разработчика на устройстве и подключите его к компьютеру с помощью USB-кабеля. Нажмите Добавить устройство, выберите устройство в диалоговом окне и нажмите Подключить.
После подключения устройства нажмите на него, чтобы настроить сборку.
В поле Select a build ID (Выбрать идентификатор сборки) выберите ветку aosp-master-with-phones-throttled, чтобы автоматически выбрать правильный образ для подключенного устройства.
Нажмите Установить, чтобы прошить устройство.
Подробную информацию о настройке можно найти в документации по Android Flash Tool. Вы также можете ознакомиться с инструкциями по созданию образа HWASan из исходного кода в документации AOSP.