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: '==9569==ERROR: HWAddressSanitizer: tag-mismatch on address 0x00433ae20045 at pc 0x00623ae2a9cc READ of size 1 at 0x00433ae20045 tags: 5b/83 (ptr/mem) in thread T0 #0 0x7240450c68 (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) #1 0x723dffd490 (/vendor/lib64/sensors.ssc.so+0x34490) #2 0x723e0126e0 (/vendor/lib64/sensors.ssc.so+0x496e0) [...] [0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5 Cause: use-after-free 0x00433ae20045 is located 5 bytes inside of 10-byte region [0x00433ae20040,0x00433ae2004a) freed by thread T0 here: #0 0x72404d1b18 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0x10b18) #1 0x723af23040 (/vendor/lib64/libgralloccore.so+0x5040) #2 0x723af23fa4 (/vendor/lib64/libgralloccore.so+0x5fa4) [...] previously allocated here: #0 0x72404ce554 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0xd554) #1 0x7240115654 (/apex/com.android.runtime/lib64/bionic/libc.so+0x43654) #2 0x7240450ac8 (/system/lib64/vndk-sp-R/libcutils.so+0x8ac8) [...] hwasan_dev_note_heap_rb_distance: 1 1023 hwasan_dev_note_num_matching_addrs: 0 hwasan_dev_note_num_matching_addrs_4b: 0 Thread: T0 0x006a00002000 stack: [0x007fc1064000,0x007fc1864000) sz: 8388608 tls: [0x00737702ffc0,0x007377033000) Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x006f33ae2000: 08 00 08 00 [83] 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. =>0x006f33ae2000: 72 .. d0 .. [..] .. .. .. .. .. .. .. .. .. .. .. 0x006f33ae2010: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags Registers where the failure occurred (pc 0x00623ae2a9cc): x0 0000007fc18623ec x1 5b0000433ae20045 x2 0000000000000013 x3 ffffffffffffffff x4 ffffffffffffffff x5 0000007fc1861da3 x6 6f7420676e696f47 x7 45522061206f6420 x8 0000000000000000 x9 0200006b00000000 x10 00000007fc18623f x11 5b0000433ae20040 x12 6f64206f7420676e x13 0a44414552206120 x14 0000000000000010 x15 ffffffffffffffff x16 000000737169ac94 x17 0000000000000007 x18 0000007377bd8000 x19 0000007fc1862498 x20 0200006b00000000 x21 0000007fc18624a8 x22 0000000000000001 x23 0000000000000000 x24 0000000000000000 x25 0000000000000000 x26 0000000000000000 x27 0000000000000000 x28 0000000000000000 x29 0000007fc1862410 x30 000000623ae2a9d0 sp 0000007fc18623d0 SUMMARY: HWAddressSanitizer: tag-mismatch (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) [ … 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 (
READrispetto aWRITE) - 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):
- L'elenco dei thread nel processo
- L'elenco dei thread nel processo
- Il valore dei tag di memoria vicino alla memoria con errori
- 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.