Android NDK obsługuje HWAddress Sanitizer, czyli HWASan, od wersji NDK r21 i Androida 10 (API na poziomie 29). HWASan jest dostępny tylko na 64-bitowych urządzeniach z architekturą Arm.
HWASan to narzędzie do wykrywania błędów pamięci podobne do ASan. W porównaniu z klasycznym ASan, HWASan ma:
- Podobny narzut na procesor (ok. 2x)
- Podobny narzut na rozmiar kodu (40–50%)
- Znacznie mniejsze obciążenie pamięci RAM (10–35%)
HWASan wykrywa ten sam zestaw błędów co ASan:
- Przepełnienie lub niedopełnienie bufora stosu i sterty
- Użycie sterty po zwolnieniu
- Stosowanie poza zakresem
- Podwójne bezpłatne lub dzikie bezpłatne
HWASan wykrywa też:
- Korzystanie z zasobów po zwrocie
Przykładowa aplikacja
Przykładowa aplikacja pokazuje, jak skonfigurować wariant kompilacji dla hwasan.
Koduj
Aby skompilować kod natywny (JNI) aplikacji za pomocą HWAddress Sanitizer, wykonaj te czynności:
ndk-build
W pliku 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)
W pliku build.gradle
modułu:
android {
defaultConfig {
externalNativeBuild {
cmake {
# Can also use system or none as ANDROID_STL, but not c++_static.
arguments "-DANDROID_STL=c++_shared"
}
}
}
}
W przypadku każdego celu w pliku CMakeLists.txt:
target_compile_options(${TARGET} PUBLIC -fsanitize=hwaddress -fno-omit-frame-pointer)
target_link_options(${TARGET} PUBLIC -fsanitize=hwaddress)
W NDK w wersji 27 lub nowszej możesz też użyć tych elementów w build.gradle
i nie musisz zmieniać pliku CMakeLists.txt:
android {
defaultConfig {
externalNativeBuild {
cmake {
arguments "-DANDROID_SANITIZE=hwaddress"
}
}
}
}
Nie będzie to działać w przypadku korzystania z ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false
.
CMake (Gradle Kotlin)
W pliku build.gradle
modułu:
android {
defaultConfig {
externalNativeBuild {
cmake {
# Can also use system or none as ANDROID_STL, but not c++_static.
arguments += "-DANDROID_STL=c++_shared"
}
}
}
}
W przypadku każdego celu w pliku CMakeLists.txt:
target_compile_options(${TARGET} PUBLIC -fsanitize=hwaddress -fno-omit-frame-pointer)
target_link_options(${TARGET} PUBLIC -fsanitize=hwaddress)
W NDK w wersji 27 lub nowszej możesz też użyć tych elementów w build.gradle
i nie musisz zmieniać pliku CMakeLists.txt:
android {
defaultConfig {
externalNativeBuild {
cmake {
arguments += "-DANDROID_SANITIZE=hwaddress"
}
}
}
}
Nie będzie to działać w przypadku korzystania z ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false
.
Android 14 lub nowszy: dodaj wrap.sh
Jeśli używasz Androida 14 lub nowszego, możesz użyć skryptu wrap.sh, aby uruchomić aplikację z możliwością debugowania na dowolnym urządzeniu z Androidem. Możesz pominąć ten krok, jeśli wykonasz czynności opisane w instrukcjach konfiguracji.
Postępuj zgodnie z instrukcjami, aby spakować skrypt wrap.sh i dodać ten skrypt wrap.sh dla arm64-v8a
.
#!/system/bin/sh
LD_HWASAN=1 exec "$@"
Uruchom
Jeśli używasz Androida w wersji starszej niż 14 lub nie dodano skryptu wrap.sh, przed uruchomieniem aplikacji postępuj zgodnie z instrukcjami konfiguracji.
Uruchom aplikację w zwykły sposób. Gdy zostanie wykryty błąd pamięci, aplikacja ulega awarii z sygnałem SIGABRT i wyświetla szczegółowy komunikat w logcat. Kopię wiadomości znajdziesz w pliku w folderze /data/tombstones
. Wygląda ona tak:
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)
Po komunikacie mogą pojawić się dodatkowe informacje do debugowania, w tym lista aktywnych wątków w aplikacji, tagi pobliskich alokacji pamięci i wartości rejestrów procesora.
Więcej informacji o komunikatach o błędach HWASan znajdziesz w artykule Interpretowanie raportów HWASan.
Tworzenie plików wykonywalnych wiersza poleceń
Na Androidzie 14 i nowszych możesz tworzyć i uruchamiać pliki wykonywalne z instrumentacją HWASan. W przypadku plików wykonywalnych możesz użyć tej samej konfiguracji, która została opisana w sekcji Kompilowanie w przypadku ndk-build lub CMake. Prześlij pliki wykonywalne na urządzenie z Androidem 14 lub nowszym i uruchom je w normalny sposób za pomocą powłoki.
Jeśli używasz biblioteki libc++, upewnij się, że korzystasz z udostępnionej biblioteki STL, i prześlij ją na urządzenie. Podczas uruchamiania pliku binarnego ustaw LD_LIBRARY_PATH
na katalog, w którym się ona znajduje.
Jeśli nie używasz Gradle, zapoznaj się z dokumentacją NDK, aby dowiedzieć się, jak tworzyć kompilacje z wiersza poleceń za pomocą CMake i ndk-build.
Android 13 lub starszy: konfiguracja
Jeśli na urządzeniu masz Androida 14 lub nowszego, możesz pominąć ten krok i postępować zgodnie z instrukcjami dotyczącymi używania wrap.sh w sekcji Kompilacja. Możesz też przejść do tej sekcji i pominąć instrukcje dotyczące używania skryptu wrap.sh.
Przed Androidem 14 aplikacje HWASan wymagały do działania kompilacji Androida z HWASan. Na obsługiwanych urządzeniach Pixel możesz przeprowadzić aktualizację do gotowych obrazów HWASan. Kompilacje są dostępne na stronie ci.android.com. Możesz tam kliknąć kwadrat odpowiadający kompilacji, którą chcesz pobrać, aby uzyskać link Flash Build. Wymaga to znajomości nazwy kodowej telefonu.
Może być łatwiej przejść bezpośrednio na stronę flash.android.com, ponieważ tam proces rozpoczyna się od wykrycia urządzenia i wyświetla tylko kompilacje, których możesz użyć. Poniższe obrazy ilustrują proces konfiguracji w tym narzędziu.
Włącz tryb programisty na urządzeniu i podłącz je do komputera za pomocą kabla USB. Kliknij Dodaj nowe urządzenie, wybierz urządzenie w oknie i kliknij Połącz.
Po podłączeniu urządzenia kliknij je, aby skonfigurować kompilację.
W polu Wybierz identyfikator kompilacji kliknij aosp-master-with-phones-throttled
gałąź, aby automatycznie wybrać odpowiedni obraz dla podłączonego urządzenia.
Aby wgrać oprogramowanie na urządzenie, kliknij Zainstaluj.
Więcej informacji o konfiguracji znajdziesz w dokumentacji narzędzia Android Flash Tool. Możesz też zapoznać się z dokumentacją AOSP, aby uzyskać instrukcje tworzenia obrazu HWASan ze źródeł.