Informazioni sui report HWASan

Quando lo strumento HWASan rileva un bug di memoria, il processo viene terminato con abort() e un report viene stampato su stderr e logcat. Come tutti gli arresti anomali nativi su Android, gli errori HWASan si trovano in /data/tombstones.

Report di esempio

Rispetto agli arresti anomali nativi regolari, HWASan contiene informazioni aggiuntive nel campo Abort message (Messaggio di interruzione) nella parte superiore del tombstone. Ecco un esempio di arresto anomalo basato sull'heap. Per i bug dello stack, consulta la nota relativa alle sezioni specifiche dello stack.

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
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 …]

È simile a un report di AddressSanitizer. A differenza di questi, quasi tutti i bug di HWASan sono errori di mancata corrispondenza dei tag, ovvero un accesso alla memoria in cui un tag del puntatore non corrisponde al tag di memoria corrispondente. Potrebbe trattarsi di una delle seguenti opzioni:

  • Accesso fuori dai limiti nello stack o nell'heap
  • Errore use-after-free nell'heap
  • Errore use-after-return nello stack

Sezioni

Di seguito è riportata una spiegazione di ciascuna sezione del report di HWASan.

Errore di accesso

Contiene informazioni sull'accesso alla memoria non valido, tra cui:

  • Tipo di accesso (READ rispetto a WRITE)
  • Dimensione dell'accesso (numero di byte a cui è stato tentato l'accesso)
  • Numero di thread dell'accesso
  • Tag del puntatore e della memoria (per il debug avanzato)

Analisi dello stack di accesso

Analisi dello stack dell'accesso alla memoria non valido. Consulta la sezione Simbolizzazione per simbolizzare.

Causa

La potenziale causa dell'accesso non valido. Se sono presenti più candidati, vengono elencati in ordine di probabilità decrescente. Precede le informazioni dettagliate sulla potenziale causa. HWASan può diagnosticare le seguenti cause:

  • Use-after-free
  • Mancata corrispondenza dei tag dello stack, che può essere use-after-return dello stack, use-after-scope dello stack o fuori dai limiti
  • Overflow del buffer dell'heap
  • Overflow globale

Informazioni sulla memoria

Descrive ciò che HWASan sa della memoria a cui si accede e può variare in base al tipo di bug:

Tipo di bug Causa Formato del report
Mancata corrispondenza dei tag Use-after-free Utilizza questo formato del report:
<address> is located N bytes inside of M-byte region [<start>, <end>)
freed by thread T0 here:
Overflow del buffer dell'heap Tieni presente che può trattarsi anche di un underflow.
<address> is located N bytes to the right of M-byte region [<start>, <end>)
allocated here:
Mancata corrispondenza dei tag dello stack I report dello stack non distinguono tra overflow o underflow e bug use-after-return. Inoltre, per trovare l'allocazione dello stack che è l'origine dell'errore, è necessario un passaggio di simbolizzazione offline. Consulta la sezione Informazioni sui report dello stack.
Liberazione non valida Use-after-free Un bug di doppia liberazione. Se ciò si verifica all'arresto del processo, può indicare una violazione della regola di definizione unica (ODR).
<address> is located N bytes inside of M-byte region [<start>, <end>)
freed by thread T0 here:
Impossibile descrivere l'indirizzo Una liberazione non valida (liberazione di memoria che non era stata allocata in precedenza) o una doppia liberazione dopo che la memoria allocata è stata rimossa dal buffer libero di HWASan.
0x... è la memoria shadow di HWASan Una liberazione non valida, in quanto l'app stava tentando di liberare la memoria interna a HWASan.

Analisi dello stack di deallocazione

Analisi dello stack del punto in cui la memoria è stata deallocata. Presente solo per i bug use-after-free o invalid-free. Consulta la sezione Simbolizzazione per simbolizzare.

Analisi dello stack di allocazione

Analisi dello stack del punto in cui la memoria è stata allocata. Consulta la sezione Simbolizzazione per simbolizzare.

Informazioni di debug avanzate

Il report di HWASan include anche alcune informazioni di debug avanzate, tra cui (in ordine):

  1. L'elenco dei thread nel processo
  2. L'elenco dei thread nel processo
  3. Il valore dei tag di memoria vicino alla memoria con errori
  4. Il dump dei registri nel punto di accesso alla memoria

Dump dei tag di memoria

Puoi utilizzare il dump della memoria dei tag per cercare allocazioni di memoria vicine con lo stesso tag del tag del puntatore. Questi tag possono indicare un accesso fuori dai limiti con un offset elevato. Un tag corrisponde a 16 byte di memoria; il tag del puntatore è costituito dai primi 8 bit dell'indirizzo. Il dump della memoria dei tag può fornire suggerimenti, ad esempio il seguente è un overflow del buffer a destra:

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  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..

Nota la sequenza di 6 × 16 = 96 byte di tag ad a sinistra che corrispondono al tag del puntatore.

Se la dimensione di un'allocazione non è un multiplo di 16, il resto della dimensione viene memorizzato come tag di memoria e il tag viene memorizzato come tag di granuli brevi. Nell'esempio precedente, subito dopo l'allocazione in grassetto con tag ad, abbiamo un'allocazione di 5 × 16 + 4 = 84 byte del tag 5c.

Un tag di memoria zero (ad esempio, tags: ad/00 (ptr/mem)) indica un bug use-after-return dello stack.

Dump dei registri

Il dump dei registri nei report di HWASan corrisponde all'istruzione che ha eseguito l'accesso alla memoria non valido. Questo dump è seguito da un altro dump dei registri dal gestore di segnali Android standard. Ignora il secondo dump, perché è stato eseguito quando HWASan ha chiamato abort() e non è pertinente al bug.

Simbolizzazione

Per ottenere i nomi delle funzioni e i numeri di riga nelle analisi dello stack (e ottenere i nomi delle variabili per i bug use-after-scope), è necessario un passaggio di simbolizzazione offline.

Prima configurazione: installa llvm-symbolizer

Per simbolizzare, il sistema deve avere llvm-symbolizer installato e accessibile da $PATH. Su Debian, puoi installarlo utilizzando sudo apt install llvm.

Ottieni i file di simboli

Per la simbolizzazione, sono necessari file binari non rimossi contenenti simboli. La loro posizione dipende dal tipo di build:

  • Per le build locali, i file di simboli si trovano in out/target/product/<product>/symbols/.
  • Per le build AOSP (ad esempio, quelle installate da Android Flash Tool), le build si trovano su Android CI. Negli artefatti della build è presente un file ${PRODUCT}-symbols-${BUILDID}.zip.
  • Per le build interne della tua organizzazione, consulta la documentazione della tua organizzazione per ricevere assistenza per l'ottenimento dei file di simboli.

Simbolizza

hwasan_symbolize --symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash

Informazioni sui report dello stack

Per i bug che si verificano con le variabili dello stack, il report di HWASan contiene dettagli come i seguenti:

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)
  [...]

Per aiutarti a comprendere i bug dello stack, HWASan tiene traccia dei frame dello stack precedenti. HWASan non li trasforma in contenuti comprensibili per l'utente nel report sui bug e richiede un passaggio di simbolizzazione aggiuntivo.

Violazioni della regola di definizione unica (ODR)

Alcuni bug use-after-free segnalati da HWASan possono indicare una violazione della regola di definizione unica (ODR). Una violazione della regola di definizione unica si verifica quando la stessa variabile viene definita più volte nello stesso programma. Ciò significa anche che la variabile viene distrutta più volte, il che può portare all'errore use-after-free.

Dopo la simbolizzazione, le violazioni della regola di definizione unica mostrano un errore use-after-free con __cxa_finalize, sia nello stack di accesso non valido sia nello stack freed here (liberato qui). Lo stack previously allocated here (allocato in precedenza qui) contiene __dl__ZN6soinfo17call_constructorsEv e dovrebbe puntare alla posizione nel programma che definisce la variabile più in alto nello stack.

La regola di definizione unica può essere violata se vengono utilizzate librerie statiche. Se una libreria statica che definisce una variabile globale C++ è collegata a più librerie condivise o eseguibili, potrebbero esistere più definizioni dello stesso simbolo nello stesso spazio di indirizzi, il che causa un errore della regola di definizione unica.

Risoluzione dei problemi

Questa sezione descrive alcuni errori e come risolverli.

HWAddressSanitizer non può descrivere l'indirizzo in modo più dettagliato

A volte HWASan può esaurire lo spazio per le informazioni sulle allocazioni di memoria precedenti. In questo caso, il report contiene una sola analisi dello stack per l'accesso alla memoria immediato, seguita da una nota:

HWAddressSanitizer can not describe address in more detail.

In alcuni casi, puoi risolvere il problema eseguendo il test più volte. Un'altra opzione è aumentare la dimensione della cronologia di HWASan. Puoi farlo a livello globale in build/soong/cc/sanitize.go (cerca hwasanGlobalOptions) o nell'ambiente del processo (prova adb shell echo $HWASAN_OPTIONS per visualizzare le impostazioni attuali).

Questo errore può verificarsi anche se la memoria a cui si accede non è mappata o allocata da un allocatore non compatibile con HWASan. In questo caso, il tag mem elencato nell'intestazione dell'arresto anomalo è in genere 00. Se hai accesso al tombstone completo, potrebbe essere utile consultare il dump delle mappe di memoria per scoprire a quale mappatura (se presente) appartiene l'indirizzo.

Bug nidificato nello stesso thread

Ciò significa che si è verificato un bug durante la generazione del report sugli arresti anomali di HWASan. In genere è dovuto a un bug nel runtime di HWASan. Se possibile, segnala un bug e fornisci le istruzioni per riprodurre il problema.