Quando a ferramenta HWASan detecta um bug de memória, o processo é encerrado com abort()
.
um relatório é impresso em stderr e logcat. Como todas as falhas nativas no Android, os erros do HWASan podem ser
encontrado abaixo de /data/tombstones
.
Em comparação com falhas nativas comuns, o HWASan carrega mais informações no campo "Cancelar mensagem". perto do topo da lápide. Veja abaixo um exemplo de falha baseada em heap. Para bugs de pilha, consulte a observação 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 …]
Esse processo é muito semelhante ao relatório AddressSanitizer. Ao contrário desses, quase todos os bugs do HWASan são “tag-mismatch”, ou seja, um acesso à memória em que uma tag ponteiro não correspondem à tag de memória correspondente. Pode ser um dos
- acesso fora dos limites na pilha ou heap
- usar após a liberação na heap
- usar após retorno na pilha
Seções
Confira abaixo uma explicação de cada uma das seções do relatório do HWASan:
Erro de acesso
Contém informações sobre o acesso inválido à memória, incluindo:
- Tipo de acesso ("READ" x "WRITE")
- Tamanho do acesso (quantos bytes houve uma tentativa de acesso)
- Número da linha de execução do acesso
- Tags de ponteiro e memória (para depuração avançada)
Acessar stack trace
Stack trace do acesso com falha à memória. Consulte a seção Simbolização para simbolizam.
Causa
A possível causa do acesso ruim. Se houver vários candidatos, eles são listados em ordem decrescente de probabilidade. Precede as informações detalhadas sobre o uma possível causa. O HWASan pode diagnosticar as seguintes causas:
- use-after-free
- incompatibilidade de tag de pilha: pode ser pilha de uso após retorno / uso posterior ao escopo ou fora dos limites
- estouro de buffer de heap
- transbordamento global
Informações sobre a memória
Descreve o que o HWASan sabe sobre a memória que está sendo acessada e pode ser diferente com base na tipo de inseto.
Tipo de inseto | Causa | Formato do relatório |
---|---|---|
incompatibilidade de tag | use-after-free |
<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
estouro de buffer de heap | Observe que isso também pode ser um subfluxo.
<address> is located N bytes to the right of M-byte region [<start>, <end>) allocated here: |
|
incompatibilidade de tag de pilha | Os relatórios de pilha não diferenciam entre estouro/subfluxo e use após o retorno. Em Além disso, para encontrar a alocação de pilha que é a origem do erro, um dispositivo off-line a etapa de simbolização é obrigatória. Consulte a seção Noções básicas sobre os relatórios de pilha seção abaixo. | |
livre de inválidos | use-after-free | Esse é um bug duplo e sem custo financeiro. Se isso acontecer no encerramento do processo, pode significar um
Violação de ODR.
<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
não é possível descrever o endereço | Pode ser muito livre (sem memória que não tenha sido alocada anteriormente) ou Dupla sem custo financeiro depois que a memória alocada foi removida do buffer livre do HWASan. | |
0x... é a memória de sombra HWAsan. | Isso é definitivamente sem custo financeiro, já que o app tentava liberar memória que é do HWASan. |
Stack trace de desalocação
Stack trace de onde a memória foi desalocada. Presente apenas para uso depois da liberação ou bugs sem valor inválido. Consulte a Seção de simbolização para simbolizar.
Stack trace de alocação
Stack trace de onde a memória foi alocada. Consulte a Seção de simbolização para simbolizar.
Depuração avançada Informações
O relatório HWASan também apresenta algumas informações avançadas de depuração, incluindo: (em ordem):
- Lista de linhas de execução no processo
- Lista de linhas de execução no processo
- Valor das tags de memória próximas à memória com falha
- O despejo dos registros no ponto de acesso à memória
Dump de tag de memória
O despejo de memória da tag pode ser usado para procurar alocações de memória próximas com a mesma tag como ponteiro tag. Isso pode apontar para um acesso fora dos limites com um grande deslocamento. Uma tag corresponde a 16 bytes de memória. a tag do ponteiro são os 8 bits principais do endereço. O despejo de memória da tag pode dar dicas para Confira a seguir 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 de "anúncio" à esquerda que correspondem à tag de ponteiro.
Se o tamanho de uma alocação não for múltiplo de 16, o restante do tamanho será armazenados como tag de memória, e a tag será armazenada como um arquivo curto grânulo interno. No exemplo acima, logo após a alocação em negrito marcada anúncio, ter 5 × 16 + 4 = alocação de 84 bytes da tag 5c.
Uma tag de memória zero (por exemplo, tags: ad/00 (ptr/mem)
) geralmente indica uma
stack-use-after-return.
Registrar despejo
O despejo de registro nos relatórios do HWASan corresponde à instrução real que executou o inválido memória acesso. Ele é seguido por outro despejo de registro do gerenciador de sinal normal do Android – ignorar o o segundo, ele é obtido quando o HWASan chamou abort() e não é relevante para o bug.
Simbolização
Para receber nomes de funções e números de linha em stack traces e nomes de variáveis para use-after-scope bugs), é necessária uma etapa de simbolização off-line.
Configuração inicial: instalar llvm-symbolizer
Para simbolizar, seu sistema precisa ter o llvm-symbolizer instalado e acessível em $PATH. No Debian, é possível
instalá-lo usando sudo apt install llvm
.
Extrair arquivos de símbolos
Para simbolização, são necessários binários com símbolos contendo símbolos. Onde eles podem ser encontrados depende com base no tipo de build:
Para versões locais, os arquivos de símbolos podem ser encontrados em
out/target/product/<product>/symbols/
Para builds do AOSP (por exemplo, atualizados pelo Flashstation), o
builds podem ser encontrados em Android CI. Na seção "Artefatos" para o
constroem,
haverá um arquivo ${PRODUCT}-symbols-${BUILDID}.zip
.
Para builds internos da sua organização, consulte a documentação da organização para receber ajuda para obter arquivos de símbolo.
Simbolizar
hwasan_symbolize –-symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash
Entender os relatórios de pilha
Para bugs que ocorrem com variáveis de pilha, o relatório do HWASan contém detalhes como estes:
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 bugs de pilha sejam compreendidos, o HWASan monitora os frames de pilha que aconteceram no passado. Atualmente, o HWASan não transforma esses dados em conteúdo compreensível para as pessoas no relatório do bug. requer uma etapa de simbolização adicional.
Violações de ODR
Alguns bugs de uso após a liberação relatados pelo HWASan também podem indicar uma violação da regra de uma definição (ODR). Uma violação de ODR acontece quando a mesma variável é definida várias vezes no mesmo programa. Isso também significa que a variável é destruída várias vezes, o que pode causar use-after-free.
Após a simbolização, as violações de ODR mostram um uso após a liberação com __cxa_finalize
,
na pilha de acesso inválido e na opção pilha. O modelo "anteriormente alocado
aqui" pilha contém __dl__ZN6soinfo17call_constructorsEv
e deve
para o local do programa que define a variável mais acima na pilha.
Um motivo pelo qual o ODR pode ser violado é quando bibliotecas estáticas são usadas. Se uma biblioteca estática que define um C++ global estiver vinculada a várias bibliotecas compartilhadas ou múltiplas definições do mesmo símbolo podem acabar no mesmo endereço o que vai causar um erro de ODR.
Solução de problemas
O 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 stack trace para acesso imediato à memória, seguido por uma observação:
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 HWASan
tamanho do histórico. Isso pode ser feito globalmente
build/soong/cc/sanitize.go
(procure por
hwasanGlobalOptions
) ou no seu ambiente de processo (experimente
adb shell echo $HWASAN_OPTIONS
para conferir as configurações atuais).
Isso também pode acontecer se a memória acessada não for mapeada ou alocada por um não HWASan
alocador. Nesse caso, a tag mem
listada no cabeçalho da falha geralmente é
00
. Se você tiver acesso à lápide completa, pode ser útil consultar o
os mapas de memória são descartados para descobrir a que mapeamento (se houver) o endereço pertence.
Bug aninhado na mesma linha de execução
Isso significa que houve um bug ao gerar o relatório de erros do HWASan. Isso geralmente ocorre devido a um bug na ambiente de execução do HWASan, registre um bug e e fornecer instruções sobre como reproduzir o problema, se possível.