Android NDK obsługuje HWAddress Sanitizer (znany też jako HWASan) od wersji NDK r21 i Androida 10 (poziom interfejsu API 29). HWASan jest dostępny tylko na 64-bitowych urządzeniach z procesorami Arm.
HWASan to narzędzie do wykrywania błędów pamięci podobne do ASan. W porównaniu z klasyczną wersją ASANA, HWASAN oferuje:
- Podobny narzut procesora (~2x)
- Nadmiarowy rozmiar kodu (40–50%)
- znacznie mniejsze obciążenie pamięci RAM (10–35%),
HWASan wykrywa te same błędy co ASan:
- przepełnienie lub niewykorzystanie bufora stosu i kupy
- Użycie sterty po zwalnianiu
- Użycie zasobów spoza zakresu
- podwójne wolne lub wolne w duchu dzikiej przyrody.
Dodatkowo HWASan wykrywa:
- Użycie stosu po powrocie
Przykładowa aplikacja
Przykładowa aplikacja pokazuje, jak skonfigurować wariant kompilacji dla hwasan.
Budowanie
Aby skompilować kod natywny (JNI) aplikacji za pomocą Sanitizera HWAddress:
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
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 27 lub nowszej wersji możesz też użyć w pliku build.gradle
następujących poleceń, nie musisz wtedy zmieniać pliku CMakeLists.txt:
android {
defaultConfig {
externalNativeBuild {
cmake {
arguments "-DANDROID_SANITIZE=hwaddress"
}
}
}
}
Nie będzie działać, gdy używasz 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 wolisz wykonać czynności opisane w instrukcjach konfiguracji.
Postępuj zgodnie z instrukcjami, aby przepakować skrypt wrap.sh i dodać go do arm64-v8a
.
#!/system/bin/sh
LD_HWASAN=1 exec "$@"
Uruchom
Jeśli używasz wersji Androida starszej niż 14 lub nie dodasz 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 SIGABRT i wypisuje szczegółowy komunikat do logcat. Kopię wiadomości znajdziesz w pliku /data/tombstones
. Wygląda on 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 debugowania, w tym lista aktywnych wątków w aplikacji, tagi przyległych alokacji pamięci i wartości rejestrów procesora.
Więcej informacji o komunikatach o błędach HWASan znajdziesz w artykule Informacje o raportach HWASan.
Tworzenie plików wykonywalnych wiersza poleceń
Na Androidzie 14 i nowszych możesz tworzyć i uruchamiać pliki wykonywalne z instrumentacją HWASan. Możesz użyć tej samej konfiguracji, jak w sekcji Tworzenie w przypadku ndk-build lub CMake w przypadku plików wykonywalnych. Prześlij pliki wykonywalne na urządzenie z Androidem 14 lub nowszym i uruchom je jak zwykle za pomocą powłoki.
Jeśli używasz biblioteki libc++, upewnij się, że używasz udostępnionej biblioteki STL i przesyłasz ją na urządzenie. Następnie ustaw LD_LIBRARY_PATH
na katalog, w którym jest ona przechowywana, gdy uruchamiasz plik binarny.
Jeśli nie używasz Gradle, zapoznaj się z dokumentacją NDK, aby dowiedzieć się, jak kompilować z poziomu wiersza poleceń za pomocą CMake i ndk-build.
Android 13 lub starszy: konfiguracja
Jeśli masz urządzenie z Androidem 14 lub nowszym, możesz pominąć ten krok i postępować zgodnie z instrukcjami dotyczącymi wrap.sh w sekcji Kompilowanie. Możesz też postępować zgodnie z instrukcjami podanymi w tej sekcji i pominąć instrukcje dotyczące korzystania z wrap.sh.
W wersjach Androida starszych niż 14 aplikacje HWASan wymagają wersji HWASan. Na obsługiwanych urządzeniach Pixel możesz flashować wstępnie utworzone obrazy HWASan. Kompilacje są dostępne na stronie ci.android.com. Możesz tam kliknąć kwadrat odpowiadający konkretnej kompilacji, aby uzyskać link do kompilacji Flash. W tym celu musisz znać nazwę kodową telefonu.
Może być łatwiej, jeśli zamiast tego przejdziesz bezpośrednio na stronę flash.android.com, ponieważ tam proces rozpoczyna się od wykrywania urządzenia i wyświetla tylko wersje, których możesz używać. Poniższe obrazy przedstawiają 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 połączeniu urządzenia kliknij je, aby skonfigurować kompilację.
W polu Wybierz identyfikator kompilacji wybierz gałąź aosp-master-with-phones-throttled
, aby automatycznie wybrać odpowiedni obraz dla podłączonego urządzenia.
Kliknij Zainstaluj, aby przeprowadzić flashowanie urządzenia.
Więcej informacji o wymaganej konfiguracji znajdziesz w dokumentacji narzędzia do instalowania oprogramowania na urządzeniach z Androidem. Możesz też zapoznać się z dokumentacją AOSP, aby dowiedzieć się, jak skompilować obraz HWASan z źródła.