Entendendo os relatórios HWASan

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 .

Em comparação com as falhas nativas regulares, o HWASan carrega informações extras no campo “Abort message” 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: '

[...]

[0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5








[ … 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
  • usar depois de livre na pilha
  • usar após retornar à 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 incorreto à memória, incluindo:

  • Tipo de acesso ("READ" vs. "WRITE")
  • Tamanho do acesso (quantos bytes foram tentados para 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 incorreto à memória. Veja a seção Simbologia para simbolizar.

Causa

A causa potencial para o mau acesso. Se houver vários candidatos, eles serão listados em ordem decrescente de probabilidade. Precede as informações detalhadas sobre a causa potencial. HWASan pode diagnosticar as seguintes causas:

  • use-after-free
  • stack tag-mismatch: pode ser uso após retorno / uso após escopo ou fora dos limites
  • estouro de buffer de heap
  • transbordamento global

Informação 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 Inseto Causa Formato do relatório
tag incompatível 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 underflow.
<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 erros de estouro/subfluxo e erros de uso após retorno. Além disso, para encontrar a alocação da pilha que é a origem do erro, é necessária uma etapa de simbolização off-line. Consulte a seção Entendendo os relatórios de pilha abaixo.
livre de inválidos use-after-free Este é um bug gratuito duplo. Se isso acontecer no encerramento do processo, isso pode significar uma violação de ODR .
<address> is located N bytes inside of M-byte region [<start>, <end>)
  freed by thread T0 here:
não pode descrever o endereço Um wild free (livre de memória que não havia sido alocada antes) ou um double free após a memória alocada ter sido removida do buffer livre do HWASan.
0x… é uma memória de sombra HWA. Este é definitivamente um livre selvagem, pois o aplicativo estava tentando liberar a memória interna do HWASan.

Rastreamento de Pilha de Desalocação

Rastreamento de pilha de onde a memória foi desalocada. Presente apenas para bugs livres de uso ou livres de inválidos. Veja a seção Simbologia para simbolizar.

Rastreamento de Pilha de Alocação

Rastreamento de pilha de onde a memória foi alocada. Veja a seção Simbologia para simbolizar.

Informações avançadas de depuração

O relatório HWASan também apresenta algumas informações avançadas de depuração, incluindo (em ordem):

  1. A lista de threads no processo
  2. A lista de threads no processo
  3. O valor dos tags de memória perto da memória com falha
  4. O despejo dos registradores no ponto de acesso à memória

Despejo de Marca de Memória

O despejo de memória do tag pode ser usado para procurar alocações de memória próximas com o mesmo tag que o tag do ponteiro. Isso pode apontar para um acesso fora dos limites com um grande deslocamento. Um tag corresponde a 16 bytes de memória; a tag do ponteiro são os 8 bits superiores do endereço. O despejo de memória do 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 etiqueta de memória e a etiqueta será armazenada como uma etiqueta de granulado curto . No exemplo acima, logo após o anúncio marcado com 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 após retorno da pilha.

Registrar Despejo

O despejo 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 regular do Android - ignore o segundo , é obtido quando HWASan chamou abort() e não é relevante para o bug.

simbolização

Para obter nomes de função 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.

Configuração inicial: instale o 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ímbolo

Para simbolização, exigimos binários não despojados contendo símbolos. Onde eles podem ser encontrados depende do tipo de construção:

Para compilações locais , os arquivos de símbolo podem ser encontrados em out/target/product/<product>/symbols/ .

Para compilações AOSP (por exemplo, flash do Flashstation ), as compilações podem ser encontradas no Android CI . Nos "Artifacts" 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 compreendidos, o HWASan acompanha os quadros de pilha que aconteceram no passado. Atualmente, o HWASan não transforma isso em conteúdo compreensível por humanos no relatório de bug e requer uma etapa de simbolização adicional .

Violações de ODR

Alguns erros de uso após a liberação relatados pelo HWASan também podem indicar uma violação da regra de definição única (ODR). Uma violação de ODR ocorre 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 levar ao erro use-after-free.

Após a simbolização, as violações de ODR mostram um use-after-free com __cxa_finalize , tanto na pilha de acesso inválido quanto na pilha "freed here". A pilha "anteriormente alocada aqui" contém __dl__ZN6soinfo17call_constructorsEv e deve apontar para o local em seu programa que define a variável mais alta na pilha.

Uma razão pela 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 executáveis, várias definições do mesmo símbolo podem acabar existindo no mesmo espaço de endereço, o que causará um erro de ODR.

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 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 tamanho do histórico do 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 travamento 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.