Limpador HWAddress

O Android NDK tem suporte ao Limpador de endereços HW (link em inglês), também conhecido como HWASan, do NDK r21 e do Android 10 em diante (nível 29 da API). O HWASan só está disponível em dispositivos Arm de 64bits.

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:

  • Excesso ou falta do buffer de heap e pilha
  • Uso de heap depois da liberação
  • Uso de pilha fora do escopo
  • Double free ou wild free

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

  • Uso de pilha após retorno

App de exemplo

Um app de exemplo (link em inglês) mostra como configurar uma variante de build para o HWASan.

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)
target_link_options(${TARGET} PUBLIC -fsanitize=hwaddress)

Com o NDK 27 ou mais recente, também é possível usar o seguinte no seu build.gradle e não seja necessário alterar o CMakeLists.txt:

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                arguments "-DANDROID_SANITIZE=hwaddress"
            }
        }
    }
}

Isso não vai funcionar ao usar ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false.

Android 14 ou versão mais recente: adicionar o wrap.sh

Se você está executando o Android 14 ou mais recente, use um script wrap.sh para executar o app depurável em qualquer dispositivo Android. Pule esta etapa se você tiver decidido seguir as etapas nas Instruções de configuração.

Siga as instruções de empacotamento de um script wrap.sh para adicionar o seguinte script wrap.sh em arm64-v8a.

#!/system/bin/sh
LD_HWASAN=1 exec "$@"

Executar

Se você está usando uma versão do Android anterior à 14 ou não adicionou um wrap.sh siga as Instruções de configuração antes de executar seu aplicativo.

Execute o app normalmente. Quando um erro de memória é detectado, um aplicativo falha com SIGABRT e mostra uma mensagem detalhada no logcat. Uma cópia da mensagem pode em um arquivo abaixo de /data/tombstones e tem 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, incluindo a lista de linhas de execução ativas no aplicativo, tags de alocação de memória próximas e valores de registro da CPU.

Consulte Noções básicas sobre os relatórios do HWASan para mais informações sobre as mensagens de erro dessa ferramenta.

Como criar executáveis de linha de comando

Você pode criar e executar executáveis instrumentados com o HWASan no Android 14 e mais recentes. Você pode usar a mesma configuração descrita em Build para ndk-build ou CMake para executáveis. Enviar os executáveis para um dispositivo executando o Android 14 ou mais recente e executando normalmente usando o shell.

Se você usar a libc++, use a STL compartilhada e envie-a para o dispositivo e defina LD_LIBRARY_PATH como o diretório que o contém quando ao executar o binário.

Se você não usa o Gradle, consulte a documentação do NDK para aprender a criar usando a linha de comando com CMake e ndk-build.

Android 13 ou versões anteriores: configuração

Se o dispositivo tiver o Android 14 ou mais recente, pule esta etapa e siga as instruções para usar o wrap.sh na seção Criar abaixo. Você também pode seguir esta seção e pular as instruções para usar o wrap.sh abaixo.

Em versões anteriores ao Android 14, os aplicativos HWASan precisam de um build HWASan do Android para serem executados. Atualize as imagens HWASan pré-criadas para dispositivos Pixel com suporte. Os builds estão disponíveis em ci.android.com, onde você pode clicar no quadrado do build exato para gerar um link de build para atualização. É necessário que você saiba o codinome do seu smartphone.

Atualização de um build do dispositivo

Pode ser mais fácil acessar flash.android.com 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 Seleção do dispositivo para se conectar

Depois que o dispositivo estiver conectado, clique 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.