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: '==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 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 aWRITE
) - 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):
- 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 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.