HWASan-Berichte

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

[...]

[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-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 zu WRITE)
  • 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):

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