Entender os relatórios do HWASan

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: '

[...]

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








[ … 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):

  1. Lista de linhas de execução no processo
  2. Lista de linhas de execução no processo
  3. Valor das tags de memória próximas à memória com falha
  4. 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.