Wenn das HWASan-Tool einen Speicherfehler erkennt, wird der Prozess mit abort() beendet und ein Bericht wird an stderr und logcat ausgegeben. Wie alle nativen Abstürze unter Android werden HWASan-Fehler unter /data/tombstones gespeichert.
Beispielbericht
Im Vergleich zu regulären nativen Abstürzen enthält HWASan zusätzliche Informationen im Feld Abort message (Abbruchmeldung) oben im Tombstone. Hier ist ein Beispiel für einen Heap-basierten Absturz. Informationen zu Stack-Fehlern finden Sie im Hinweis zu den Stack-spezifischen 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-Mismatch-Fehler, d. h. ein Speicherzugriff, bei dem ein Pointer-Tag nicht mit dem entsprechenden Speicher-Tag übereinstimmt. Dies kann eine der folgenden Ursachen haben:
- Zugriff außerhalb des zulässigen Bereichs auf Stack oder Heap
- Use-after-free-Fehler auf dem Heap
- Use-after-return-Fehler auf dem Stack
Abschnitte
Hier finden Sie eine Erläuterung der einzelnen Abschnitte des HWASan-Berichts.
Zugriffsfehler
Enthält Informationen zum fehlerhaften Speicherzugriff, einschließlich:
- Zugriffstyp (
READim Vergleich zuWRITE) - Zugriffsgröße (Anzahl der Bytes, auf die zugegriffen werden sollte)
- Threadnummer des Zugriffs
- Pointer- und Speicher-Tags (für erweiterte Fehlerbehebung)
Stack-Trace des Zugriffs
Stack-Trace des fehlerhaften Speicherzugriffs. Informationen zur Symbolisierung finden Sie unter Symbolisierung.
Ursache
Die mögliche Ursache für den fehlerhaften Zugriff. Wenn es mehrere mögliche Ursachen gibt, werden sie in absteigender Reihenfolge der Wahrscheinlichkeit aufgeführt. Geht den detaillierten Informationen zur möglichen Ursache voraus. HWASan kann die folgenden Ursachen diagnostizieren:
- Use after free
- Stack-Tag-Mismatch, der auf eine Verwendung des Stacks nach der Rückgabe, eine Verwendung des Stacks nach dem Gültigkeitsbereich oder einen Zugriff außerhalb des zulässigen Bereichs zurückzuführen sein kann
- Heap-Pufferüberlauf
- Globaler Überlauf
Speicherinformationen
Beschreibt, was HWASan über den Zugriff auf den Speicher weiß, und kann je nach Fehlertyp variieren:
| Fehlertyp | Ursache | Berichtsformat |
|---|---|---|
| Tag-Mismatch | 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 | Dies kann auch ein Unterlauf sein.<address> is located N bytes to the right of M-byte region [<start>, <end>) allocated here: |
|
| Stack-Tag-Mismatch | In Stack-Berichten wird nicht zwischen Überlauf oder Unterlauf und Use-after-return-Fehlern 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 Stack Berichte verstehen. | |
| Ungültige Freigabe | Use after free | Ein Double-Free-Fehler. Wenn dies beim Herunterfahren des Prozesses geschieht, 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 „Wild Free“ (Freigabe von Speicher, der zuvor nicht zugewiesen wurde) oder eine Double Free, nachdem der zugewiesene Speicher aus dem kostenlosen Puffer von HWASan entfernt wurde. | |
| 0x... ist der Schattenarbeitsspeicher von HWASan | Eine „Wild Free“, da die App versucht hat, Speicher freizugeben, der intern für HWASan verwendet wird. |
Stack-Trace der Freigabe
Stack-Trace der Stelle, an der der Speicher freigegeben wurde. Nur für Use-after-free- oder Invalid-free-Fehler vorhanden. Informationen zur Symbolisierung finden Sie unter Symbolisierung.
Stack-Trace der Zuweisung
Stack-Trace der Stelle, an der der Speicher zugewiesen wurde. Informationen zur Symbolisierung finden Sie unter Symbolisierung.
Erweiterte Debugging-Informationen
Der HWASan-Bericht enthält auch einige erweiterte Debugging-Informationen, darunter (in dieser Reihenfolge):
- Die Liste der Threads im Prozess
- Die Liste der Threads im Prozess
- Der Wert der Speicher-Tags in der Nähe des fehlerhaften Speichers
- Der Dump der Register zum Zeitpunkt des Speicherzugriffs
Speicher-Tag-Dump
Mit dem Speicher-Tag-Dump können Sie nach Speicherzuweisungen in der Nähe suchen, die dasselbe Tag wie das Pointer-Tag haben. Diese Tags können auf einen Zugriff außerhalb des zulässigen Bereichs mit einem großen Offset hinweisen. Ein Tag entspricht 16 Byte Speicher. Das Pointer-Tag sind die obersten 8 Bit der Adresse. Der Speicher-Tag-Dump kann Hinweise geben. Das folgende Beispiel zeigt einen Pufferüberlauf nach rechts:
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 6 × 16 = 96 Byte mit 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 der
Speicher-Tag gespeichert und das Tag als ein Short
Granule-Tag. Im vorherigen Beispiel haben wir direkt nach der fett gedruckten Zuweisung mit dem Tag ad eine 5 × 16 + 4 = 84 Byte große Zuweisung mit dem Tag 5c.
Ein Speicher-Tag mit dem Wert 0 (z. B. tags: ad/00 (ptr/mem)) weist auf einen
Use-after-return-Fehler hin.
Register-Dump
Der Register-Dump in HWASan-Berichten entspricht der Anweisung, die den ungültigen Speicherzugriff ausgeführt hat. Auf diesen Dump folgt ein weiterer Register-Dump vom regulären Android-Signal-Handler. Ignorieren Sie den zweiten Dump, da er erstellt 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 Use-after-scope-Fehler zu erhalten), ist ein Offline-Symbolisierungsschritt erforderlich.
Ersteinrichtung: llvm-symbolizer installieren
Für die Symbolisierung muss llvm-symbolizer auf Ihrem System installiert und über $PATH zugänglich sein. Unter Debian können Sie es mit sudo apt install llvm installieren.
Symboldateien abrufen
Für die Symbolisierung benötigen wir nicht entfernte Binärdateien, die Symbole enthalten. Der Speicherort hängt vom Typ des Builds ab:
- Bei lokalen Builds befinden sich die Symboldateien in
out/target/product/<product>/symbols/. - Bei AOSP-Builds (z. B. mit
dem Android Flash Tool geflasht) befinden sich die
Builds in Android CI. In den Artifacts für den Build befindet sich eine Datei
${PRODUCT}-symbols-${BUILDID}.zip. - Bei internen Builds Ihrer Organisation finden Sie in der Dokumentation Ihrer Organisation Informationen zum Abrufen von Symboldateien.
Symbolisieren
hwasan_symbolize --symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash
Stack-Berichte verstehen
Bei Fehlern, die mit Stack-Variablen auftreten, 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) [...]
Um Stack-Fehler zu verstehen, verfolgt HWASan frühere Stack-Frames. HWASan wandelt diese nicht in für Menschen verständliche Inhalte im Fehlerbericht um und erfordert einen zusätzlichen Symbolisierungsschritt.
Verstöße gegen die ODR
Einige von HWASan gemeldete Use-after-free-Fehler können auf einen Verstoß gegen die One Definition Rule (ODR) hinweisen. Ein ODR-Verstoß tritt auf, wenn dieselbe Variable mehrmals im selben Programm definiert wird. Das bedeutet auch, dass die Variable mehrmals zerstört wird, was zu dem 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 des ungültigen Zugriffs als auch im Stack freed here (hier freigegeben). Der Stack previously allocated here (zuvor hier zugewiesen) enthält __dl__ZN6soinfo17call_constructorsEv und sollte auf die Stelle in Ihrem Programm verweisen, an der die Variable weiter oben im Stack definiert ist.
Die ODR kann verletzt werden, wenn statische Bibliotheken verwendet werden. Wenn eine statische Bibliothek, die eine globale C++-Variable definiert, mit mehreren gemeinsam genutzten Bibliotheken oder ausführbaren Dateien verknüpft ist, können mehrere Definitionen desselben Symbols im selben Adressraum vorhanden sein, was zu einem ODR-Fehler führt.
Fehlerbehebung
In diesem Abschnitt werden einige Fehler und Möglichkeiten zur Behebung beschrieben.
HWAddressSanitizer kann die Adresse nicht genauer beschreiben
Manchmal reicht der Speicherplatz für Informationen zu früheren Speicherzuweisungen nicht aus. In diesem Fall enthält der Bericht nur einen Stack-Trace für den unmittelbaren Speicherzugriff, gefolgt von einem Hinweis:
HWAddressSanitizer can not describe address in more detail.
In einigen Fällen können Sie dieses Problem beheben, indem Sie den Test mehrmals ausführen. Eine weitere Möglichkeit besteht darin, die HWASan-Verlaufsgröße zu erhöhen. Sie können dies global in build/soong/cc/sanitize.go tun (suchen Sie nach hwasanGlobalOptions) oder in Ihrer Prozessumgebung (versuchen Sie adb shell echo $HWASAN_OPTIONS, um die aktuellen Einstellungen zu sehen).
Dieser Fehler kann auch auftreten, wenn der zugegriffene Speicher nicht zugeordnet oder von einem Allocator zugewiesen wurde, der nicht HWASan-kompatibel ist. In diesem Fall ist das im Absturzkopf aufgeführte mem-Tag in der Regel 00. Wenn Sie Zugriff auf den vollständigen Tombstone haben, kann es hilfreich sein, den Dump der Speicherzuordnungen zu prüfen, um herauszufinden, zu welcher Zuordnung (falls vorhanden) die Adresse gehört.
Verschachtelter Fehler im selben Thread
Das bedeutet, dass beim Generieren des HWASan-Absturzberichts ein Fehler aufgetreten ist. Dies ist in der Regel auf einen Fehler in der HWASan-Laufzeit zurückzuführen. Melden Sie einen Fehler und geben Sie nach Möglichkeit eine Anleitung zur Reproduktion des Problems an.