HWASan-Berichte verstehen

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

[...]

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








[ … 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):

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