Como depurar a corrupção de memória usando o Limpador de endereços

Este documento mostra como ativar ferramentas de depuração especiais ao usar a AGDE. Essas ferramentas podem ajudar com erros de corrupção de memória e substituição difíceis de diagnosticar.

Limpador HWAddress e Limpador de endereços

Limpador HWAddress (HWASan) eLimpador de endereços (ASan) são ferramentas de depuração de corrupção de memória que ajudam a depurar erros de corrupção de memória e substituição, como estes:

  • Overflows e underflows de buffer de pilha
  • Overflows e underflows de buffer de heap
  • Uso de pilha fora do escopo
  • Erros double free e wild free
  • Uso da pilha após o retorno (somente HWASan)
.

Recomendamos ativar o HWASan ou o ASan somente quando você estiver depurando um problema ou como parte de testes automatizados. Embora essas ferramentas tenham bom desempenho, o uso delas gera uma penalidade.

Comportamento do tempo de execução

Quando ativados, o HWASan e ASan verificam automaticamente a corrupção de memória de todo o tempo de execução do app.

Se um erro de memória for detectado, o app falha com um erro de SIGBART (cancelamento de sinal) e mostra uma mensagem detalhada no logcat. Uma cópia da mensagem também é gravada em um arquivo em /data/tombstones.

A mensagem de erro é semelhante a esta:

ERROR: HWAddressSanitizer: tag-mismatch on address 0x0042a0826510 at pc 0x007b24d90a0c
WRITE of size 1 at 0x0042a0826510 tags: 32/3d (ptr/mem) in thread T0
    #0 0x7b24d90a08  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x2a08)
    #1 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)
    #2 0x7b8f1db364  (/apex/com.android.art/lib64/libart.so+0x18f364)
    #3 0x7b8f2ad8d4  (/apex/com.android.art/lib64/libart.so+0x2618d4)

0x0042a0826510 is located 0 bytes to the right of 16-byte region [0x0042a0826500,0x0042a0826510)
allocated here:
    #0 0x7b92a322bc  (/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so+0x212bc)
    #1 0x7b24d909e0  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x29e0)
    #2 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)

Pré-requisitos

Instalar um build do HWASan do SO Android

Para usar o HWASan, siga as instruções de configuração na documentação do HWASan para instalar um build do HWASan do SO Android para dispositivos Google Pixel.

Para outros dispositivos, entre em contato com o fabricante para receber um build do HWASan do SO, se disponível, ou use a ferramenta ASan somente de software.

Usar a biblioteca C++ padrão compartilhada no projeto

Devido a um problema conhecido, o ASan é incompatível com o tratamento de exceções de C++ ao usar libc++_static. Esse problema não ocorre quando libc++_shared é usado.

O HWASan tem sua própria implementação dos operadores new e delete, que não podem ser usados se a biblioteca padrão estiver estaticamente vinculada ao projeto.

Para mudar essa configuração, consulte a seção Como vincular a biblioteca C++ padrão deste documento.

Ativar a geração de ponteiro do frame

O HWASan e o ASan usam um unwinder baseado em ponteiro de frames rápido para gerar informações de stack trace para eventos de alocação e desalocação de memória. Isso significa que você precisa ativar a geração de ponteiro do frame nas configurações do compilador C++ para usar esses recursos. Ou seja, é necessário desativar a otimização da omissão do ponteiro do frame.

Para mudar essa configuração, consulte a seção Como ativar a geração de ponteiro do frame deste documento.

Como configurar o projeto do Visual Studio para usar o HWASan ou o ASan

Como ativar o HWASan ou o ASan

Para ativar o HWASan ou o ASan, acesse Configuration Properties > General nas Property Pages (páginas de propriedades) do projeto.

Menu de propriedades do Solution Explorer do Visual Studio para o projeto
atual.

Figura 1: a opção Properties do projeto na janela do Solution Explorer do Visual Studio.

A caixa de diálogo "Property Pages" do projeto com as propriedades gerais exibidas e as configurações do Limpador de
endereços em destaque.

Figura 2: a configuração Address Sanitizer (ASan) nas propriedades gerais do projeto.

Para ativar o HWASan no projeto, mude a configuração Address Sanitizer (ASan) para Hardware ASan Enabled (fsanitize=hwaddress).

Para ativar o ASan no projeto, mude a configuração Address Sanitizer (ASan) para ASan Enabled (fsanitize=hwaddress).

Como ativar a geração de ponteiro do frame

A geração de ponteiro do frame é controlada pela configuração do compilador C/C++ Omit Frame Pointer e pode ser encontrada nas Property Pages do projeto em Configuration Properties > C/C++ > Optimization.

A caixa de diálogo "Property Pages" do projeto com as propriedades de otimização C/C++ mostradas
e as configurações "Omit Frame Pointer"
em destaque.

Figura 3: onde encontrar a configuração Omit Frame Pointer.

Ao usar o HWASan ou o ASan, defina a configuração Omit Frame Pointer como No (-fno-omit-frame-pointer).

Como vincular a biblioteca C++ padrão no modo de biblioteca compartilhada

A configuração do modo do vinculador para a biblioteca C++ padrão pode ser encontrada nas Property Pages do projeto em Configuration Properties > General, na seção Project Defaults.

A caixa de diálogo "Property Pages" do projeto com a categoria General selecionada e a
configuração "Use of STL"
destacada.

Figura 4: onde encontrar a configuração do modo do vinculador para a biblioteca C++ padrão.

Ao usar o HWASan ou o ASan, defina Use of STL como Use C++ Standard Libraries (.so). Esse valor vincula a biblioteca C++ padrão ao projeto como uma biblioteca compartilhada, necessária para que o HWASan e o ASan funcionem corretamente.

Como criar uma configuração do build para uso do Limpador de endereços

Se você preferir usar o HWASan ou o ASan temporariamente, talvez não queira criar uma nova configuração do build apenas para uso dela. Isso pode acontecer se o projeto for pequeno, se você estiver explorando o recurso ou em resposta a um problema descoberto durante os testes.

No entanto, se você achar que ela é útil e planeja usá-la regularmente, crie uma nova configuração do build para o HWASan ou o ASan, conforme demonstrado no exemplo Teapot. Isso pode ser feito se, por exemplo, você executar o Limpador de endereços regularmente como parte dos testes de unidade ou durante testes de fumaça feitos de um dia para o outro.

A criação de uma configuração do build separada pode ser especialmente útil se você tiver um projeto grande que consome um grande número de bibliotecas de terceiros diferentes, onde você normalmente as vincula estaticamente à biblioteca C++ padrão. As configurações de build dedicadas podem ajudar a garantir que as configurações do projeto permaneçam sempre precisas.

Para criar uma configuração de buiild, nas Property Pages do projeto, clique no botão Configuration Manager… e abra o menu suspenso Active solution configuration. Selecione e crie uma nova configuração do build com um nome adequado (por exemplo, HWASan ativado).