Wenn das HWASan-Tool einen Speicherfehler erkennt, wird der Prozess mit abort()
beendet und ein Bericht wird in stderr und logcat ausgegeben. Wie alle nativen Abstürze unter Android werden HWASan-Fehler unter /data/tombstones
aufgeführt.
Beispielbericht
Im Vergleich zu normalen nativen Abstürzen enthält HWASan zusätzliche Informationen im Feld Abort message (Abbruchsmeldung) oben im Tombstone. Hier ist ein Beispiel für einen heapbasierten Absturz. Informationen zu Stack-Fehlern finden Sie in den Hinweisen zu den stackspezifischen Abschnitten.
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** Build fingerprint: 'google/flame_hwasan/flame:Tiramisu/MASTER/7956676:userdebug/dev-keys' Revision: 'DVT1.0' ABI: 'arm64' Timestamp: 2019-04-24 01:13:22+0000 pid: 11154, tid: 11154, name: sensors@1.0-ser >>> /vendor/bin/hw/android.hardware.sensors@1.0-service <<< signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr -------- Abort message: '==9569==ERROR: HWAddressSanitizer: tag-mismatch on address 0x00433ae20045 at pc 0x00623ae2a9cc READ of size 1 at 0x00433ae20045 tags: 5b/83 (ptr/mem) in thread T0 #0 0x7240450c68 (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) #1 0x723dffd490 (/vendor/lib64/sensors.ssc.so+0x34490) #2 0x723e0126e0 (/vendor/lib64/sensors.ssc.so+0x496e0) [...] [0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5 Cause: use-after-free 0x00433ae20045 is located 5 bytes inside of 10-byte region [0x00433ae20040,0x00433ae2004a) freed by thread T0 here: #0 0x72404d1b18 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0x10b18) #1 0x723af23040 (/vendor/lib64/libgralloccore.so+0x5040) #2 0x723af23fa4 (/vendor/lib64/libgralloccore.so+0x5fa4) [...] previously allocated here: #0 0x72404ce554 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0xd554) #1 0x7240115654 (/apex/com.android.runtime/lib64/bionic/libc.so+0x43654) #2 0x7240450ac8 (/system/lib64/vndk-sp-R/libcutils.so+0x8ac8) [...] hwasan_dev_note_heap_rb_distance: 1 1023 hwasan_dev_note_num_matching_addrs: 0 hwasan_dev_note_num_matching_addrs_4b: 0 Thread: T0 0x006a00002000 stack: [0x007fc1064000,0x007fc1864000) sz: 8388608 tls: [0x00737702ffc0,0x007377033000) Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x006f33ae2000: 08 00 08 00 [83] 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. =>0x006f33ae2000: 72 .. d0 .. [..] .. .. .. .. .. .. .. .. .. .. .. 0x006f33ae2010: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags Registers where the failure occurred (pc 0x00623ae2a9cc): x0 0000007fc18623ec x1 5b0000433ae20045 x2 0000000000000013 x3 ffffffffffffffff x4 ffffffffffffffff x5 0000007fc1861da3 x6 6f7420676e696f47 x7 45522061206f6420 x8 0000000000000000 x9 0200006b00000000 x10 00000007fc18623f x11 5b0000433ae20040 x12 6f64206f7420676e x13 0a44414552206120 x14 0000000000000010 x15 ffffffffffffffff x16 000000737169ac94 x17 0000000000000007 x18 0000007377bd8000 x19 0000007fc1862498 x20 0200006b00000000 x21 0000007fc18624a8 x22 0000000000000001 x23 0000000000000000 x24 0000000000000000 x25 0000000000000000 x26 0000000000000000 x27 0000000000000000 x28 0000000000000000 x29 0000007fc1862410 x30 000000623ae2a9d0 sp 0000007fc18623d0 SUMMARY: HWAddressSanitizer: tag-mismatch (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) [ … regular crash dump follows …]
Dies ähnelt einem AddressSanitizer-Bericht. Im Gegensatz dazu sind fast alle HWASan-Fehler Tag-Nichtübereinstimmungsfehler, d. h. ein Speicherzugriff, bei dem ein Zeiger-Tag nicht mit dem entsprechenden Speicher-Tag übereinstimmt. Mögliche Ursachen:
- Zugriff außerhalb des Gültigkeitsbereichs auf Stack oder Heap
- Use-after-free-Fehler im Heap
- „Use-after-return“-Fehler im Stack
Abschnitte
Im Folgenden werden die einzelnen Abschnitte des HWASan-Berichts erläutert.
Zugriffsfehler
Enthält Informationen zum fehlerhaften Speicherzugriff, darunter:
- Zugriffstyp (
READ
im Vergleich zuWRITE
) - Zugriffsgröße (wie viele Byte wurden versucht zuzugreifen)
- Threadnummer des Zugriffs
- Zeiger- und Speicher-Tags (für erweitertes Debugging)
Auf Stack-Trace zugreifen
Stack-Trace des fehlerhaften Speicherzugriffs. Weitere Informationen finden Sie unter Symbolisierung.
Ursache
Die potenzielle Ursache für den fehlerhaften Zugriff. Wenn es mehrere Kandidaten gibt, werden sie in absteigender Wahrscheinlichkeit aufgeführt. Vor den detaillierten Informationen zur möglichen Ursache. HWASan kann die folgenden Ursachen diagnostizieren:
- Use After Free
- Nicht übereinstimmendes Stack-Tag, z. B. Stack-Nutzung nach Rückgabe, Stack-Nutzung nach Gültigkeitsbereich oder „Out of Bounds“
- Heap-Pufferüberlauf
- Globaler Überlauf
Arbeitsspeicherinformationen
Beschreibt, was HWASan über den Speicher weiß, auf den zugegriffen wird. Dies kann je nach Fehlertyp variieren:
Fehlertyp | Ursache | Berichtsformat |
---|---|---|
Abweichendes Tag | Use After Free | Verwenden Sie dieses Berichtsformat:<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
Heap-Pufferüberlauf | Beachten Sie, dass dies auch ein Unterlauf sein kann.<address> is located N bytes to the right of M-byte region [<start>, <end>) allocated here: |
|
Nicht übereinstimmendes Stack-Tag | In Stack-Berichten wird nicht zwischen Über- oder Unterlauf und Fehlern vom Typ „Verwendung nach Rückgabe“ unterschieden. Außerdem ist ein Offline-Symbolisierungsschritt erforderlich, um die Stack-Zuweisung zu finden, die die Ursache des Fehlers ist. Weitere Informationen finden Sie unter Stapelberichte. | |
Ungültiges Attribut „free“ | Use After Free | Ein Fehler beim doppelten Freigeben. Wenn dies beim Herunterfahren des Prozesses auftritt, kann dies auf einen Verstoß gegen die ODR hinweisen.
<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
Adresse kann nicht beschrieben werden | Entweder eine wilde Freigabe (Freigabe von Speicher, der zuvor nicht zugewiesen wurde) oder eine doppelte Freigabe, nachdem der zugewiesene Speicher aus dem kostenlosen Puffer von HWASan entfernt wurde. | |
0x… ist HWAsan-Schattenspeicher | Ein wilder Fehler, da die App versucht hat, Speicher freizugeben, der intern zu HWASan gehört. |
Stack-Trace der Deaktivierung
Stacktrace, an dem der Arbeitsspeicher deallociert wurde. Nur für „Use-after-free“- oder „Invalid-Free“-Fehler vorhanden. Weitere Informationen finden Sie unter Symbolisierung.
Zuweisungs-Stack-Trace
Stacktrace, an dem der Arbeitsspeicher zugewiesen wurde. Weitere Informationen finden Sie unter Symbolisierung.
Informationen zur erweiterten Fehlerbehebung
Der HWASan-Bericht enthält auch einige erweiterte Informationen zur Fehlerbehebung, darunter (in der Reihenfolge):
- Die Liste der Threads im Prozess
- Die Liste der Threads im Prozess
- Der Wert der Arbeitsspeicher-Tags in der Nähe des fehlerhaften Arbeitsspeichers
- Der Dump der Register zum Zeitpunkt des Speicherzugriffs
Speicher-Tag-Dump
Mit dem Tag-Speicherdump können Sie nach Speicherzuweisungen in der Nähe suchen, die dasselbe Tag wie das Zeiger-Tag haben. Diese Tags können auf einen Zugriff außerhalb des Gültigkeitsbereichs mit einem großen Offset hinweisen. Ein Tag entspricht 16 Byte Arbeitsspeicher. Das Pointer-Tag sind die ersten 8 Bits der Adresse. Der Tag-Speicherdump kann Hinweise geben. Im folgenden Beispiel ist rechts ein Pufferüberlauf zu sehen:
tags: ad/5c (ptr/mem) [...] Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: 0e 0e 0e 57 20 20 20 20 20 2e 5e 5e 5e 5e 5e b5 =>0x006f33ae2000: f6 f6 f6 f6 f6 4c ad ad ad ad ad ad [5c] 5c 5c 5c 0x006f33ae2010: 5c 04 2e 2e 2e 2e 2e 2f 66 66 66 66 66 80 6a 6a Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: ab 52 eb .. .. .. .. .. .. .. .. .. .. .. .. .. =>0x006f33ae2000: .. .. .. .. .. .. .. .. .. .. .. .. [..] .. .. .. 0x006f33ae2010: .. 5c .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Beachten Sie die Folge von 6 × 16 = 96 Byte ad
-Tags links, die mit dem Pointer-Tag übereinstimmen.
Wenn die Größe einer Zuweisung kein Vielfaches von 16 ist, wird der Rest der Größe als Speicher-Tag gespeichert und das Tag als Short-Granule-Tag. Im vorherigen Beispiel folgt direkt nach der fett formatierten Zuweisung mit dem Tag ad
eine Zuweisung von 5 × 16 + 4 = 84 Byte für das Tag 5c
.
Ein Null-Speicher-Tag (z. B. tags: ad/00 (ptr/mem)
) weist auf einen Stack-Fehler nach dem Rückgabewert hin.
Register-Dump
Der Registerdump in HWASan-Berichten entspricht der Anweisung, die den ungültigen Speicherzugriff ausgeführt hat. Auf diesen Dump folgt ein weiterer Registerdump vom regulären Android-Signalhandler. Ignorieren Sie den zweiten Dump, da er aufgenommen wurde, als HWASan abort()
aufgerufen hat, und für den Fehler nicht relevant ist.
Symbolisierung
Um Funktionsnamen und Zeilennummern in Stack-Traces zu erhalten (und Variablennamen für Fehler vom Typ „Verwendung nach Gültigkeitsbereich“ zu erhalten), ist ein Offline-Symbolisierungsschritt erforderlich.
Ersteinrichtung: llvm-symbolizer installieren
Dazu muss llvm-symbolizer
auf Ihrem System installiert und von $PATH
aus zugänglich sein. Unter Debian können Sie es mit sudo apt install llvm
installieren.
Symboldateien abrufen
Für die Symbolisierung sind nicht gestrippte Binärdateien mit Symbolen erforderlich. Die Position hängt vom Buildtyp ab:
- Bei lokalen Builds befinden sich die Symboldateien in
out/target/product/<product>/symbols/
. - Für AOSP-Builds (z. B. über das Android Flash Tool geflasht) werden die Builds in Android CI ausgeführt. Unter den Artefakten für den Build befindet sich eine
${PRODUCT}-symbols-${BUILDID}.zip
-Datei. - Informationen zum Abrufen von Symboldateien für interne Builds Ihrer Organisation finden Sie in der Dokumentation Ihrer Organisation.
Symbolisieren
hwasan_symbolize --symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash
Stapelberichte
Bei Fehlern mit Stackvariablen enthält der HWASan-Bericht Details wie diese:
Cause: stack tag-mismatch Address 0x007d4d251e80 is located in stack of thread T64 Thread: T64 0x0074000b2000 stack: [0x007d4d14c000,0x007d4d255cb0) sz: 1088688 tls: [0x007d4d255fc0,0x007d4d259000) Previously allocated frames: record_addr:0x7df7300c98 record:0x51ef007df3f70fb0 (/apex/com.android.art/lib64/libart.so+0x570fb0) record_addr:0x7df7300c90 record:0x5200007df3cdab74 (/apex/com.android.art/lib64/libart.so+0x2dab74) [...]
HWASan protokolliert die bisherigen Stackframes, um Ihnen bei der Behebung von Stack-Fehlern zu helfen. HWASan wandelt diese nicht in für Menschen verständliche Inhalte im Fehlerbericht um und erfordert einen zusätzlichen Symbolisierungsschritt.
Verstöße gegen die Online-Streitbeilegung
Einige von HWASan gemeldete Fehler vom Typ „Use-after-Free“ können auf einen Verstoß gegen die One Definition Rule (ODR) hinweisen. Ein ODR-Verstoß liegt vor, wenn dieselbe Variable mehrmals im selben Programm definiert ist. Das bedeutet auch, dass die Variable mehrmals destruktiert wird, was zu einem „Use-After-Free“-Fehler führen kann.
Nach der Symbolisierung zeigen ODR-Verstöße einen „Use-After-Free“-Fehler mit __cxa_finalize
sowohl im Stack für ungültige Zugriffe als auch im Stack freed here an. Der Stapel previously allocated here enthält __dl__ZN6soinfo17call_constructorsEv
und sollte auf die Stelle in Ihrem Programm verweisen, an der die Variable weiter oben im Stapel definiert wird.
Die ODR kann verletzt werden, wenn statische Bibliotheken verwendet werden. Wenn eine statische Bibliothek, die ein C++-Globales definiert, mit mehreren freigegebenen Bibliotheken oder ausführbaren Dateien verknüpft ist, können im selben Adressraum mehrere Definitionen desselben Symbols vorhanden sein, was zu einem ODR-Fehler führt.
Fehlerbehebung
In diesem Abschnitt werden einige Fehler beschrieben und wie Sie sie beheben können.
HWAddressSanitizer kann Adresse nicht genauer beschreiben
Manchmal kann in HWASan nicht mehr genügend Speicherplatz für Informationen zu früheren Speicherzuweisungen zur Verfügung stehen. In diesem Fall enthält der Bericht nur einen Stack-Trace für den direkten Speicherzugriff, gefolgt von einer Notiz:
HWAddressSanitizer can not describe address in more detail.
In einigen Fällen lässt sich das Problem beheben, indem Sie den Test mehrmals ausführen. Eine weitere Möglichkeit besteht darin, die Größe des HWASan-Verlaufs zu erhöhen. Das ist global in build/soong/cc/sanitize.go
(hwasanGlobalOptions
suchen) oder in der Prozessumgebung möglich (adb shell echo $HWASAN_OPTIONS
für die aktuellen Einstellungen).
Dieser Fehler kann auch auftreten, wenn der zugegriffene Arbeitsspeicher nicht zugeordnet oder von einem nicht HWASan-kompatiblen Allocator zugewiesen wird. In diesem Fall ist das in der Crash-Überschrift aufgeführte mem
-Tag in der Regel 00
. Wenn Sie Zugriff auf den vollständigen Tombstone haben, kann es hilfreich sein, den Dump der Speicherzuordnung zu prüfen, um herauszufinden, zu welcher Zuordnung (falls vorhanden) die Adresse gehört.
Verschachtelter Fehler im selben Thread
Das bedeutet, dass beim Erstellen des HWASan-Absturzberichts ein Fehler aufgetreten ist. Dies ist in der Regel auf einen Fehler in der HWASan-Laufzeit zurückzuführen. Melden Sie den Fehler und geben Sie nach Möglichkeit eine Anleitung zum Reproduzieren des Problems an.