Informazioni sui report HWASan

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

Report di esempio

Rispetto agli arresti anomali nativi standard, HWASan contiene informazioni aggiuntive nel campo Abort message nella parte superiore della tomba. 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 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 uno dei seguenti:

  • Accesso fuori limite su stack o heap
  • Errore di uso dopo svuotamento nell'heap
  • Errore di utilizzo dopo il ritorno nello stack

Sezioni

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

Errore di accesso

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

  • Tipo di accesso (READ rispetto a WRITE)
  • Dimensioni di accesso (quanti byte sono stati oggetto di un tentativo di accesso)
  • Numero di thread dell'accesso
  • Tag di puntatore e memoria (per il debug avanzato)

Accedere alla traccia dello stack

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

Causa

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

  • Use-after-free
  • Mancata corrispondenza del tag di stack, che può essere utilizzo dello stack dopo il ritorno, utilizzo dello stack dopo l'ambito o fuori intervallo
  • Overflow del buffer dell'heap
  • Sovrabbondanza globale

Informazioni sulla memoria

Descrive ciò che HWASan sa della memoria a cui viene eseguito l'accesso 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 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 sottoflusso.
<address> is located N bytes to the right of M-byte region [<start>, <end>)
allocated here:
Mancata corrispondenza del tag di serie I report sugli stack non fanno distinzione tra errori di overflow o underflow e bug di utilizzo dopo il ritorno. Inoltre, per trovare l'allocazione dello stack che è la fonte dell'errore, è necessario un passaggio di simbolizzazione offline. Consulta Informazioni sui report sulla pila.
Non valido Use after free Un bug di doppio scambio. Se ciò si verifica all'arresto del processo, potrebbe indicare una violazione delle norme relative alla risoluzione delle controversie.
<address> is located N bytes inside of M-byte region [<start>, <end>)
freed by thread T0 here:
Impossibile descrivere l'indirizzo Un free non valido (memoria libera che non era stata allocata in precedenza) o un free doppio dopo che la memoria allocata è stata espulsa dal buffer libero di HWASan.
0x… è una memoria HWAsan shadow Un valore libero, poiché l'app stava tentando di liberare la memoria interna di HWASan.

Traccia dello stack di deallocazione

Analisi dello stack del punto in cui la memoria è stata deallocata. Presente solo per bug di uso dopo sblocco o senza errori. Per simbolizzare, consulta la sezione Simbolizzazione.

Traccia dello stack di allocazione

Analisi dello stack della posizione in cui è stata allocata la memoria. Per simbolizzare, consulta la sezione Simbolizzazione.

Informazioni di debug avanzate

Il report 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 del tag di memoria

Puoi utilizzare il dump della memoria del tag per cercare allocazioni di memoria nelle vicinanze con lo stesso tag del tag del cursore. Questi tag possono indicare un accesso fuori limite con un offset elevato. Un tag corrisponde a 16 byte di memoria; il tag del puntatore è costituito dagli 8 bit più alti dell'indirizzo. Il dump della memoria del 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 x 16 = 96 byte di tag ad a sinistra che corrispondono al tag del cursore.

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 contrassegnata comead, abbiamo un'allocazione di 5 x 16 + 4 = 84 byte del tag 5c.

Un tag di memoria pari a zero (ad esempio tags: ad/00 (ptr/mem)) indica un bug di utilizzo dello stack dopo il ritorno.

Dump del registro

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

Simbolizzazione

Per ottenere i nomi delle funzioni e i numeri di riga nelle tracce dello stack (e i nomi delle variabili per i bug di utilizzo dopo ambito), è necessario un passaggio di simbolizzazione offline.

Prima configurazione: installa llvm-symbolizer

Per fare un esempio, sul sistema deve essere installato llvm-symbolizer e deve essere accessibile da $PATH. Su Debian, puoi installarlo utilizzando sudo apt install llvm.

Ottenere i file dei simboli

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

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

Simbolizzare

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

Informazioni sui report sugli stack

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

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 passati. HWASan non li trasforma in contenuti comprensibili per gli esseri umani nella segnalazione di bug e richiede un passaggio di simbolizzazione aggiuntivo.

Violazioni ODR

Alcuni bug di uso dopo svuotamento segnalati da HWASan possono indicare una violazione della regola One Definition Rule (ODR). Una violazione ODR 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 di uso dopo svuotamento.

Dopo la simbolizzazione, le violazioni ODR mostrano un errore di uso dopo svuotamento con __cxa_finalize sia nello stack di accesso non valido sia nello stack liberato qui. Lo stack allocato precedentemente qui contiene __dl__ZN6soinfo17call_constructorsEv e deve indicare la posizione nel programma che definisce la variabile più in alto nello stack.

Le norme ODR possono essere violate se vengono utilizzate librerie statiche. Se una libreria statica che definisce un parametro globale C++ è collegata a più librerie condivise o executable, nello stesso spazio indirizzi potrebbero esistere più definizioni dello stesso simbolo, causando un errore ODR.

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ò non avere spazio per le informazioni sulle allocazioni di memoria passate. In questo caso, il report contiene una sola traccia dello stack per l'accesso immediato alla memoria, 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 le dimensioni della cronologia HWASan. Puoi farlo a livello globale in build/soong/cc/sanitize.go (cerca hwasanGlobalOptions) o nell'ambiente di processo (prova adb shell echo $HWASAN_OPTIONS per visualizzare le impostazioni correnti).

Questo errore può verificarsi anche se la memoria a cui è stato eseguito l'accesso non è mappata o allocata da un allocatore non consapevole di HWASan. In questo caso, il tag mem elencato nell'intestazione dell'errore è generalmente 00. Se hai accesso alla tomba completa, 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. Di solito, questo problema è dovuto a un bug nel runtime HWASan. Segnala un bug e fornisci istruzioni su come riprodurre il problema, se possibile.