HWAddress-Sanitizer

Das Android NDK unterstützt HWAddress Sanitizer, auch HWASan genannt, ab NDK r21 und Android 10 (API-Level 29). HWASan ist nur auf 64-Bit-Arm-Geräten verfügbar.

HWASan ist ein Tool zur Erkennung von Speicherfehlern, das ASan ähnelt. Im Vergleich zu klassischem ASan bietet HWASan:

  • Ähnlicher CPU-Overhead (~2x)
  • Ähnlicher Overhead bei der Codegröße (40–50%)
  • Deutlich geringerer RAM-Overhead (10 % bis 35%)

HWASan erkennt dieselben Fehler wie ASan:

  • Stack- und Heap-Buffer-Overflow oder -Underflow
  • Heap-Nutzung nach dem Freigeben
  • Stack außerhalb des Gültigkeitsbereichs verwendet
  • Doppelfrei oder kostenlos in der Wildnis

Außerdem erkennt HWASan:

  • Stapelnutzung nach Rückgabe

Beispiel-App

In einer Beispiel-App wird gezeigt, wie eine Buildvariante für hwasan konfiguriert wird.

Entwickeln

So erstellen Sie den nativen (JNI) Code Ihrer App mit dem HWAddress Sanitizer:

ndk-build

In Ihrer Application.mk-Datei:

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

In der build.gradle-Datei Ihres Moduls:

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                # Can also use system or none as ANDROID_STL, but not c++_static.
                arguments "-DANDROID_STL=c++_shared"
            }
        }
    }
}

Für jedes Ziel in CMakeLists.txt:

target_compile_options(${TARGET} PUBLIC -fsanitize=hwaddress -fno-omit-frame-pointer)
target_link_options(${TARGET} PUBLIC -fsanitize=hwaddress)

Mit NDK 27 oder höher können Sie auch Folgendes in build.gradle verwenden und müssen CMakeLists.txt nicht ändern:

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                arguments "-DANDROID_SANITIZE=hwaddress"
            }
        }
    }
}

Das funktioniert nicht, wenn ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false verwendet wird.

Android 14 oder höher: Fügen Sie „wrap.sh“ hinzu.

Wenn Sie Android 14 oder höher verwenden, können Sie mit einem wrap.sh-Script Ihre debuggbare App auf jedem Android-Gerät ausführen. Diesen Schritt können Sie überspringen, wenn Sie der Anleitung zur Einrichtung gefolgt sind.

Folgen Sie der Anleitung zum Paketieren eines wrap.sh-Scripts, um das folgende wrap.sh-Script für arm64-v8a hinzuzufügen.

#!/system/bin/sh
LD_HWASAN=1 exec "$@"

Laufen

Wenn Sie eine Android-Version verwenden, die älter als 14 ist, oder kein wrap.sh-Script hinzugefügt haben, folgen Sie der Anleitung zur Einrichtung, bevor Sie Ihre App ausführen.

Führen Sie die App wie gewohnt aus. Wenn ein Arbeitsspeicherfehler erkannt wird, stürzt eine App mit SIGABRT ab und druckt eine detaillierte Meldung in logcat aus. Eine Kopie der Nachricht befindet sich in einer Datei unter /data/tombstones und sieht so aus:

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)

Auf die Meldung können zusätzliche Informationen zur Fehlerbehebung folgen, einschließlich einer Liste der aktiven Threads in der Anwendung, Tags für Speicherzuweisungen in der Nähe und CPU-Registerwerte.

Weitere Informationen zu HWASan-Fehlermeldungen finden Sie unter HWASan-Berichte.

Befehlszeilen-Ausführprogramme erstellen

Sie können ausführbare Dateien, die mit HWASan instrumentiert sind, unter Android 14 und höher erstellen und ausführen. Sie können dieselbe Konfiguration wie unter Build für ndk-build oder CMake für Ihre ausführbaren Dateien verwenden. Übertragen Sie die ausführbaren Dateien auf ein Gerät mit Android 14 oder höher und führen Sie sie wie gewohnt über die Shell aus.

Wenn Sie libc++ verwenden, achten Sie darauf, dass Sie die freigegebene STL verwenden und sie auf das Gerät übertragen. Legen Sie beim Ausführen des Binärprogramms LD_LIBRARY_PATH auf das Verzeichnis fest, in dem sich die STL befindet.

Wenn Sie Gradle nicht verwenden, lesen Sie in der NDK-Dokumentation nach, wie Sie mit CMake und ndk-build über die Befehlszeile erstellen.

Android 13 oder niedriger: Einrichtung

Wenn auf Ihrem Gerät Android 14 oder höher installiert ist, können Sie diesen Schritt überspringen und der Anleitung zur Verwendung von wrap.sh im Abschnitt Build folgen. Sie können auch diesem Abschnitt folgen und die Anleitung zur Verwendung von wrap.sh überspringen.

Vor Android 14 benötigen HWASan-Anwendungen zum Ausführen eine HWASan-Build-Version von Android. Sie können vorkonfigurierte HWASan-Images auf unterstützte Pixel-Geräte flashen. Die Builds sind unter ci.android.com verfügbar. Klicken Sie dort auf das Feld für den gewünschten Build, um einen Link zum Flash-Build aufzurufen. Dazu müssen Sie den Codenamen Ihres Smartphones kennen.

Geräteversion flashen

Es ist möglicherweise einfacher, direkt zu flash.android.com zu gehen, da dort der Vorgang mit der Erkennung Ihres Geräts beginnt und nur Builds angezeigt werden, die Sie verwenden können. Die folgenden Bilder veranschaulichen den Einrichtungsablauf in diesem Tool.

Aktivieren Sie den Entwicklermodus auf Ihrem Gerät und verbinden Sie es über ein USB-Kabel mit Ihrem Computer. Klicken Sie auf Neues Gerät hinzufügen, wählen Sie Ihr Gerät im Dialogfeld aus und klicken Sie auf Verbinden.

Gerät zum Flashen erkennen Gerät auswählen, mit dem eine Verbindung hergestellt werden soll

Klicken Sie nach der Verbindung auf das Gerät, um den Build zu konfigurieren. Wählen Sie im Feld Build-ID auswählen den Branch aosp-master-with-phones-throttled aus, damit das richtige Image automatisch für das verbundene Gerät ausgewählt wird.

Gerät auswählen, auf dem das Firmware-Update installiert werden soll Flash-Optionen bestätigen und das Gerät flashen

Klicken Sie auf Installieren, um Ihr Gerät zu flashen.

Weitere Informationen zur erforderlichen Einrichtung finden Sie in der Dokumentation zum Android-Flash-Tool. Alternativ finden Sie in der AOSP-Dokumentation eine Anleitung zum Erstellen eines HWASan-Images aus der Quelle.