Wenn das HWASan-Tool einen Speicherfehler erkennt, wird der Prozess mit abort() beendet und ein Bericht an stderr und logcat gedruckt. Wie alle nativen Abstürze unter Android sind HWASan-Fehler unter /data/tombstones
zu finden.
Im Vergleich zu normalen nativen Abstürzen enthält HWASan zusätzliche Informationen im Feld „Abbruchnachricht“ oben auf dem Tombstone. Unten sehen Sie ein Beispiel für einen Heap-basierten Absturz (Informationen zu Stack-Fehlern finden Sie im Hinweis unten zu den Stack-spezifischen Abschnitten).
Beispielbericht
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 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 ist einem AddressSanitizer -Bericht sehr ähnlich. Im Gegensatz dazu handelt es sich bei fast allen HWASan-Bugs um „Tag-Mismatch“, also einen Speicherzugriff, bei dem ein Zeiger-Tag nicht mit dem entsprechenden Speicher-Tag übereinstimmt. Dies könnte einer davon sein
- Zugriff außerhalb der Grenzen auf Stack oder Heap
- Nach dem Freigeben auf dem Heap verwenden
- Verwendung nach Rückkehr auf den Stapel
Abschnitte
Nachfolgend finden Sie eine Erläuterung der einzelnen Abschnitte des HWASan-Berichts:
Zugriffsfehler
Enthält Informationen über den fehlerhaften Speicherzugriff, einschließlich:
- Zugriffstyp („READ“ vs. „WRITE“)
- Zugriffsgröße (wie viele Bytes versucht wurden, darauf zuzugreifen)
- Thread-Nummer des Zugriffs
- Zeiger- und Speichertags (für erweitertes Debugging)
Greifen Sie auf Stack Trace zu
Stacktrace des fehlerhaften Speicherzugriffs. Informationen zur Symbolisierung finden Sie im Abschnitt „Symbolisierung“.
Ursache
Die mögliche Ursache für den schlechten Zugang. Wenn es mehrere Kandidaten gibt, werden diese in der Reihenfolge absteigender Wahrscheinlichkeit aufgelistet. Vorgestellt sind die detaillierten Informationen zur möglichen Ursache. HWASan kann folgende Ursachen diagnostizieren:
- Nachnutzung kostenlos
- Stack-Tag-Nichtübereinstimmung: Dies kann Stack-Use-After-Return/Use-After-Scope oder außerhalb der Grenzen sein
- Heap-Puffer-Überlauf
- globaler Überlauf
Speicherinformationen
Beschreibt, was HWASan über den Speicher weiß, auf den zugegriffen wird, und kann je nach Fehlertyp unterschiedlich sein.
Fehlertyp | Ursache | Berichtsformat |
---|---|---|
Tag-Nichtübereinstimmung | Nachnutzung kostenlos | <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: | |
Stack-Tag-Nichtübereinstimmung | Stack-Berichte unterscheiden nicht zwischen Überlauf-/Unterlauf- und Use-after-Return-Bugs. Darüber hinaus ist ein Offline-Symbolisierungsschritt erforderlich, um die Stapelzuordnung zu finden, die die Fehlerquelle darstellt. Weitere Informationen finden Sie weiter unten im Abschnitt „Stack-Berichte verstehen“ . | |
ungültig-frei | Nachnutzung kostenlos | Dies ist ein doppelt kostenloser Fehler. Wenn dies beim Herunterfahren des Prozesses geschieht, kann dies auf einen ODR-Verstoß hinweisen.<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
Adresse kann nicht beschrieben werden | Entweder ein Wild-Free (Freigabe von Speicher, der zuvor nicht zugewiesen wurde) oder ein Double-Free, nachdem der zugewiesene Speicher aus dem freien Puffer von HWASan entfernt wurde. | |
0x… ist HWAsan-Schattenspeicher. | Dies ist definitiv ein wilder Free-Vorgang, da die Anwendung versucht hat, internen Speicher von HWASan freizugeben. |
Freigabe-Stack-Trace
Stapelverfolgung, wo der Speicher freigegeben wurde. Nur für Use-After-Free- oder Invalid-Free-Bugs vorhanden. Informationen zur Symbolisierung finden Sie im Abschnitt „Symbolisierung“.
Zuordnungs-Stack-Trace
Stapelverfolgung, wo der Speicher zugewiesen wurde. Informationen zur Symbolisierung finden Sie im Abschnitt „Symbolisierung“.
Erweiterte Debugging-Informationen
Der HWASan-Bericht enthält auch einige erweiterte Debugging-Informationen, darunter (in der Reihenfolge):
- Die Liste der Threads im Prozess
- Die Liste der Threads im Prozess
- Der Wert der Speichertags in der Nähe des fehlerhaften Speichers
- Der Dump der Register zum Zeitpunkt des Speicherzugriffs
Speicher-Tag-Dump
Der Tag-Speicherauszug kann verwendet werden, um nach Speicherzuordnungen in der Nähe zu suchen, die dasselbe Tag wie das Zeiger-Tag haben. Diese könnten auf einen Zugriff außerhalb der Grenzen mit einem großen Offset hinweisen. Ein Tag entspricht 16 Byte Speicher; Das Zeiger-Tag sind die oberen 8 Bits der Adresse. Der Tag-Memory-Dump kann Hinweise geben, zum Beispiel das Folgende ist ein Pufferüberlauf auf der rechten Seite:
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 Reihe von 6 × 16 = 96 Bytes „ad“-Tags links, die mit dem Zeiger-Tag übereinstimmen).
Wenn die Größe einer Zuordnung kein Vielfaches von 16 ist, wird der Rest der Größe als Speichertag und das Tag als kurzes Granulat-Tag gespeichert. Im obigen Beispiel direkt nach der fett markierten Zuordnung mit der Tag-Anzeige haben wir eine 5 × 16 + 4 = 84-Byte-Zuordnung von Tag 5c.
Ein Null-Speicher-Tag (z. B. tags: ad/ 00 (ptr/mem)
) weist normalerweise auf einen Stack-Use-After-Return-Fehler hin.
Dump registrieren
Der Register-Dump in HWASan-Berichten entspricht der tatsächlichen Anweisung, die den ungültigen Speicherzugriff durchgeführt hat. Es folgt ein weiterer Register-Dump des regulären Android-Signalhandlers. Ignorieren Sie den zweiten , er wird erstellt, wenn HWASan abort() aufruft, und ist für den Fehler nicht relevant.
Symbolisierung
Um Funktionsnamen und Zeilennummern in Stack-Traces abzurufen (und Variablennamen für Use-after-Scope-Bugs zu erhalten), ist ein Offline-Symbolisierungsschritt erforderlich.
Erstmalige Einrichtung: llvm-symbolizer installieren
Zum Symbolisieren muss auf Ihrem System llvm-symbolizer installiert und über $PATH zugänglich sein. Unter Debian können Sie es mit sudo apt install llvm
installieren.
Erhalten Sie Symboldateien
Für die Symbolisierung benötigen wir ungekürzte Binärdateien, die Symbole enthalten. Wo diese zu finden sind, hängt von der Art des Builds ab:
Für lokale Builds sind die Symboldateien in out/target/product/<product>/symbols/
zu finden.
Bei AOSP-Builds (z. B. geflasht von Flashstation ) sind die Builds auf Android CI zu finden. In den „Artefakten“ für den Build gibt es eine Datei „${PRODUCT}-symbols-${BUILDID}.zip“.
Überprüfen Sie für interne Builds Ihrer Organisation die Dokumentation Ihrer Organisation, um Hilfe beim Abrufen von Symboldateien zu erhalten.
Symbolisieren
hwasan_symbolize –-symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash
Stack-Berichte verstehen
Für Fehler, die bei 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 nachvollziehen zu können, verfolgt HWASan die Stack-Frames, die in der Vergangenheit aufgetreten sind. Derzeit wandelt HWASan dies im Fehlerbericht nicht in für Menschen verständliche Inhalte um und erfordert einen zusätzlichen Symbolisierungsschritt .
ODR-Verstöße
Einige von HWASan gemeldete Use-After-Free-Fehler können auch auf einen Verstoß gegen die One Definition Rule (ODR) hinweisen. Eine ODR-Verletzung tritt auf, wenn dieselbe Variable mehrmals im selben Programm definiert wird. Dies bedeutet auch, dass die Variable mehrmals zerstört wird, was zum Use-After-Free-Fehler führen kann.
Nach der Symbolisierung zeigen ODR-Verstöße eine Verwendung nach dem Freigeben mit __cxa_finalize
sowohl auf dem ungültigen Zugriffsstapel als auch auf dem „hier freigegeben“-Stack. Der „zuvor hier zugewiesene“ Stapel enthält __dl__ZN6soinfo17call_constructorsEv
und sollte auf die Stelle in Ihrem Programm verweisen, die die Variable weiter oben im Stapel definiert.
Ein Grund, warum die ODR verletzt werden kann, ist die Verwendung statischer Bibliotheken. Wenn eine statische Bibliothek, die ein C++-Global 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
„HWAddressSanitizer kann die Adresse nicht detaillierter beschreiben.“
Manchmal kann HWASan nicht mehr genügend Speicherplatz für Informationen über vergangene Speicherzuweisungen haben. 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 manchen Fällen lässt sich dieses Problem beheben, indem der Test mehrmals ausgeführt wird. Eine weitere Möglichkeit besteht darin, die Größe des HWASan-Verlaufs zu erhöhen. Dies kann global in build/soong/cc/sanitize.go
(suchen Sie nach hwasanGlobalOptions
) oder in Ihrer Prozessumgebung (versuchen Sie adb shell echo $HWASAN_OPTIONS
, um die aktuellen Einstellungen anzuzeigen) erfolgen.
Dies kann auch passieren, wenn der Speicher, auf den zugegriffen wird, nicht zugeordnet oder von einem nicht HWASan-fähigen Allokator zugewiesen ist. In diesem Fall lautet das im Absturzheader aufgeführte mem
Tag im Allgemeinen 00
. Wenn Sie Zugriff auf den vollständigen Tombstone haben, kann es hilfreich sein, den Speicherkarten-Dump zu konsultieren, um herauszufinden, zu welcher Zuordnung (falls vorhanden) die Adresse gehört.
„Verschachtelter Fehler im selben Thread“
Dies 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. Bitte melden Sie einen Fehler und geben Sie nach Möglichkeit Anweisungen, wie das Problem reproduziert werden kann.