Android NDK поддерживает HWAddress Sanitizer , также известный как HWASan, начиная с NDK r21 и Android 10 (уровень API 29). HWASan доступен только на 64-битных устройствах Arm.
HWASan — это инструмент обнаружения ошибок памяти, аналогичный ASan. По сравнению с классическим ASan, HWASan обладает следующими преимуществами:
- Аналогичные накладные расходы на ЦП (~в 2 раза)
- Аналогичные накладные расходы на размер кода (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 "$@"
Бегать
If you're running on an Android version older than 14, or didn't add a wrap.sh script, follow the Setup Instructions before running your app.
Запустите приложение как обычно. При обнаружении ошибки памяти приложение аварийно завершает работу с сигналом 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 в разделе «Сборка» . Вы также можете следовать инструкциям в этом разделе и пропустить их.
Для работы приложений, использующих HWASan, до Android 14 требовалась сборка Android, использующая HWASan. Вы можете установить предварительно собранные образы HWASan на поддерживаемые устройства Pixel. Сборки доступны на сайте ci.android.com , где вы можете нажать на квадратик с нужной вам сборкой, чтобы получить ссылку для прошивки . Для этого вам необходимо знать кодовое имя вашего телефона .

Возможно, проще будет сразу перейти на flash.android.com, поскольку там процесс начинается с определения вашего устройства и показывает только те сборки, которые вы можете использовать. Следующие изображения иллюстрируют процесс настройки в этом инструменте.
Включите режим разработчика на вашем устройстве и подключите его к компьютеру с помощью USB-кабеля. Нажмите «Добавить новое устройство» , выберите ваше устройство в диалоговом окне и нажмите «Подключить» .


После подключения устройства нажмите на него, чтобы настроить сборку. В поле «Выберите идентификатор сборки» выберите ветку aosp-master-with-phones-throttled чтобы автоматически выбрать правильный образ для подключенного устройства.


Нажмите «Установить» , чтобы прошить ваше устройство.
Более подробная информация о необходимой настройке содержится в документации Android Flash Tool . В качестве альтернативы, вы можете обратиться к документации AOSP за инструкциями по сборке образа HWASan из исходного кода.