Quando a ferramenta HWASan detecta um bug de memória, o processo é encerrado com abort() e um relatório é impresso em stderr e logcat. Como todas as falhas nativas no Android, os erros HWASan podem ser encontrados em /data/tombstones
.
Comparado a travamentos nativos regulares, o HWASan carrega informações extras no campo “Mensagem de aborto” próximo ao topo da lápide. Veja um exemplo de falha baseada em heap abaixo (para bugs de pilha, veja a nota abaixo para as seções específicas da pilha).
Exemplo de relatório
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 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 …]
Isso é muito semelhante a um relatório AddressSanitizer . Ao contrário desses, quase todos os bugs do HWASan são “tag-mismatch”, ou seja, um acesso à memória onde uma tag de ponteiro não corresponde à tag de memória correspondente. Este pode ser um dos
- acesso fora dos limites na pilha ou heap
- use depois de grátis no heap
- use após o retorno na pilha
Seções
Uma explicação de cada uma das seções do relatório HWASan está abaixo:
Erro de acesso
Contém informações sobre o acesso inválido à memória, incluindo:
- Tipo de acesso ("LER" vs. "GRAVAR")
- Tamanho de acesso (quantos bytes foram tentados a serem acessados)
- Número da linha de acesso
- Tags de ponteiro e memória (para depuração avançada)
Acessar rastreamento de pilha
Rastreamento de pilha do acesso inválido à memória. Consulte a seção Simbolização para simbolizar.
Causa
A causa potencial para o mau acesso. Se houver vários candidatos, eles serão listados em ordem de probabilidade decrescente. Precede as informações detalhadas sobre a causa potencial. O HWASan pode diagnosticar as seguintes causas:
- use-after-free
- stack tag-mismatch: isso pode ser stack use-after-return/use after-scope, ou fora dos limites
- estouro de buffer de pilha
- estouro global
Informações de memória
Descreve o que o HWASan sabe sobre a memória que está sendo acessada e pode diferir com base no tipo de bug.
Tipo de Bug | Causa | Formato do relatório |
---|---|---|
incompatibilidade de tags | use-after-free | <address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
estouro de buffer de pilha | Observe que isso também pode ser um underflow.<address> is located N bytes to the right of M-byte region [<start>, <end>) allocated here: | |
incompatibilidade de tags de pilha | Os relatórios de pilha não diferenciam erros de estouro/esgoto e bugs de uso após o retorno. Além disso, para encontrar a alocação de pilha que é a origem do erro, é necessária uma etapa de simbolização offline. Consulte a seção Noções básicas sobre relatórios de pilha abaixo. | |
livre de inválidos | use-after-free | Este é um bug duplo livre.<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
não pode descrever o endereço | Ou um wild free (livre de memória que não havia sido alocada antes) ou um double free depois que a memória alocada foi despejada do buffer livre do HWASan. | |
0x… é a memória sombra HWAsan. | Este é definitivamente um livre selvagem, pois o aplicativo estava tentando liberar memória interna ao HWASan. |
Rastreamento de pilha de desalocação
Rastreamento de pilha de onde a memória foi desalocada. Presente apenas para bugs sem uso posterior ou sem inválidos. Consulte a seção Simbolização para simbolizar.
Rastreamento de pilha de alocação
Rastreamento de pilha de onde a memória foi alocada. Consulte a seção Simbolização para simbolizar.
Informações de depuração avançadas
O relatório HWASan também apresenta algumas informações de depuração avançadas, incluindo (em ordem):
- A lista de threads no processo
- A lista de threads no processo
- O valor das tags de memória perto da memória com falha
- O dump dos registradores no ponto de acesso à memória
Despejo de Tag de Memória
O dump de memória de tag pode ser usado para procurar alocações de memória próximas com a mesma tag que a tag de ponteiro. Estes podem apontar para um acesso fora dos limites com um grande deslocamento. Uma tag corresponde a 16 bytes de memória; a tag de ponteiro são os 8 bits superiores do endereço. O despejo de memória da tag pode fornecer dicas, por exemplo, o seguinte é um estouro de buffer à direita:
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 .. .. .. .. .. .. .. .. .. .. .. .. .. ..(observe a execução de 6 × 16 = 96 bytes de tags “ad” à esquerda que correspondem à tag de ponteiro).
Se o tamanho de uma alocação não for um múltiplo de 16, o restante do tamanho será armazenado como a tag de memória e a tag será armazenada como uma tag de grânulos curtos . No exemplo acima, logo após o anúncio marcado de alocação em negrito, temos uma alocação de 5 × 16 + 4 = 84 bytes da tag 5c.
Uma tag de memória zero (ex. tags: ad/ 00 (ptr/mem)
) geralmente indica um bug de uso de pilha após retorno.
Despejo de registro
O dump de registro nos relatórios HWASan corresponde à instrução real que executou o acesso inválido à memória. Ele é seguido por outro despejo de registro do manipulador de sinal Android regular - ignore o segundo , é obtido quando o HWASan chamou abort() e não é relevante para o bug.
Simbolização
Para obter nomes de funções e números de linha em rastreamentos de pilha (e obter nomes de variáveis para bugs de uso após o escopo), é necessária uma etapa de simbolização offline.
Primeira configuração: instale llvm-symbolizer
Para simbolizar, seu sistema deve ter o llvm-symbolizer instalado e acessível a partir de $PATH. No Debian, você pode instalá-lo usando sudo apt install llvm
.
Obter arquivos de símbolos
Para simbolização, exigimos binários não extraídos contendo símbolos. Onde eles podem ser encontrados depende do tipo de compilação:
Para compilações locais , os arquivos de símbolos podem ser encontrados em out/target/product/<product>/symbols/
.
Para compilações AOSP (por exemplo, flashed do Flashstation ), as compilações podem ser encontradas no Android CI . Nos "Artefatos" para a compilação, haverá um arquivo `${PRODUCT}-symbols-${BUILDID}.zip`.
Para compilações internas de sua organização, verifique a documentação de sua organização para obter ajuda na obtenção de arquivos de símbolos.
Simbolizar
hwasan_symbolize –-symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash
Noções básicas sobre relatórios de pilha
Para bugs que ocorrem com variáveis de pilha, o relatório HWASan conterá detalhes como este:
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) [...]
Para permitir que os bugs de pilha sejam entendidos, o HWASan mantém o controle dos quadros de pilha que aconteceram no passado. Atualmente, o HWASan não transforma isso em conteúdo compreensível para humanos no relatório de bug e requer uma etapa de simbolização adicional .
Solução de problemas
"HWAddressSanitizer não pode descrever o endereço com mais detalhes."
Às vezes, o HWASan pode ficar sem espaço para informações sobre alocações de memória anteriores. Nesse caso, o relatório conterá apenas um rastreamento de pilha para o acesso imediato à memória, seguido de uma nota:
HWAddressSanitizer can not describe address in more detail.
Em alguns casos, isso pode ser resolvido executando o teste várias vezes. Outra opção é aumentar o tamanho do histórico HWASan. Isso pode ser feito globalmente em build/soong/cc/sanitize.go
(procure por hwasanGlobalOptions
), ou em seu ambiente de processo (tente adb shell echo $HWASAN_OPTIONS
para ver as configurações atuais).
"bug aninhado no mesmo tópico"
Isso significa que houve um bug ao gerar o relatório de falha do HWASan. Isso geralmente ocorre devido a um bug no tempo de execução do HWASan, registre um bug e forneça instruções sobre como reproduzir o problema, se possível.