HWASan-Berichte

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: '

[...]

[0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5








[ … 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 (READ im Vergleich zu WRITE)
  • 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):

  1. Die Liste der Threads im Prozess
  2. Die Liste der Threads im Prozess
  3. Der Wert der Speicher-Tags in der Nähe des fehlerhaften Speichers
  4. 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.