Limpador HWAddress

O Android NDK é compatível com o Limpador de endereços HW (HWASan, na sigla em inglês), começando com NDK r21 e Android 10 (API de nível 29).

O HWASan é uma ferramenta de detecção de erros de memória semelhante ao ASan. Em comparação com o ASan clássico, o HWASan tem:

  • sobrecarga de CPU semelhante (~2x);
  • Sobrecarga de tamanho de código semelhante (40 a 50%)
  • Sobrecarga de RAM muito menor (10% a 35%)

O HWASan detecta o mesmo conjunto de bugs do ASan:

  • Overflow/underflow do buffer de heap e pilha
  • Uso de heap depois de Free
  • Uso de pilha fora do escopo
  • Double free/wild free

Além disso, o HWASan também detecta:

  • Uso em pilha após retorno

Configurar

Os aplicativos HWASan precisam de um build HWASan do Android para serem executados. É possível atualizar as imagens HWASan pré-criadas para dispositivos Pixel compatíveis. Os builds estão disponíveis em ci.android.com (link em inglês), onde você pode clicar no build exato (quadrada) que você quer para gerar um link de build para atualização. É necessário que você saiba o codinome do seu smartphone.

Atualizar um build do dispositivo

Pode ser mais fácil acessar flash.android.com (em inglês) diretamente, porque o fluxo começa com a detecção do dispositivo e mostra apenas as versões que você pode usar. As imagens a seguir ilustram o fluxo de configuração nessa ferramenta.

Ative o modo de desenvolvedor no dispositivo e o conecte ao computador usando um cabo USB. Clique em Add new device, selecione seu dispositivo na caixa de diálogo e clique em Connect.

Detectar um dispositivo para atualizar Selecione o dispositivo para se conectar

Depois que o dispositivo estiver conectado, você precisará clicar nele para configurar o build. Na caixa Select a build ID, selecione a ramificação aosp-master-with-phones-throttled para escolher automaticamente a imagem correta para o dispositivo conectado.

Selecione o dispositivo a ser atualizado Confirme as opções de atualização e atualize o dispositivo

Clique em Install para atualizar o dispositivo.

Veja mais detalhes sobre a configuração necessária na documentação do Android Flash Tool. Ou consulte a documentação do AOSP para ver instruções sobre como criar uma imagem HWASan a partir da origem.

Criar

Para criar o código nativo (JNI) do seu app com o Limpador de endereços HW (link em inglês), faça o seguinte:

ndk-build

No seu arquivo Application.mk:

APP_STL := c++_shared # Or system, or none, but not c++_static.
APP_CFLAGS := -fsanitize=hwaddress -fno-omit-frame-pointer
APP_LDFLAGS := -fsanitize=hwaddress

CMake

No arquivo build.gradle do seu módulo:

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                # Can also use system or none as ANDROID_STL, but not c++_static.
                arguments "-DANDROID_STL=c++_shared"
            }
        }
    }
}

Para cada destino no CMakeLists.txt:

target_compile_options(${TARGET} PUBLIC -fsanitize=hwaddress -fno-omit-frame-pointer)
set_target_properties(${TARGET} PROPERTIES LINK_FLAGS -fsanitize=hwaddress)

Executar

Execute o app como de costume em uma imagem do Android criada pelo HWASan. Quando um erro de memória for detectado, um app falhará com SIGABRT e exibirá uma mensagem detalhada no logcat. Uma cópia da mensagem poderá ser encontrada em um arquivo abaixo de /data/tombstones e terá esta aparência:

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)

A mensagem pode ser seguida de outras informações de depuração, como a lista de linhas de execução ativas no aplicativo, tags de alocações de memória próximas, valores de registro de CPU e assim por diante.