HWAddress Sanitizer

El NDK de Android admite HWAddress Sanitizer a partir del NDK r21 y Android 10 (API nivel 29).

HWASan es una herramienta de detección de errores de memoria similar a ASan. En comparación con la versión clásica de ASan, HWASan tiene las siguientes características:

  • Sobrecarga de la CPU similar (alrededor de 2 veces más)
  • Sobrecarga del tamaño de código similar (del 40 al 50%)
  • Sobrecarga de la RAM mucho menor (del 10 al 35%)

HWASan detecta el mismo conjunto de errores que ASan:

  • Desabastecimiento de búfer de pila
  • Uso de pila después de liberación
  • Uso de pila fuera del alcance
  • Cierre doble o cierre wild

Además, HWASan también detecta lo siguiente:

  • Uso de pila después de mostrar

Cómo configurar

Las aplicaciones HWASan necesitan una compilación HWASan de Android para ejecutarse. Puedes instalar imágenes HWASan compiladas previamente en dispositivos Pixel compatibles. Las compilaciones están disponibles en ci.android.com. Allí puedes hacer clic en la compilación exacta (cuadro) de la que deseas obtener el vínculo para instalarla. Es necesario que conozcas el nombre interno de tu teléfono.

Instala una compilación en el dispositivo

Quizás sea más fácil visitar directamente flash.android.com, ya que allí el flujo comienza con la detección de tu dispositivo y solo muestra las compilaciones que puedes usar. En las siguientes imágenes, se muestra el flujo de configuración en esta herramienta.

Habilita el modo de desarrollador en el dispositivo y luego conecta ese dispositivo a la computadora con un cable USB. Haz clic en Agregar nuevo dispositivo, selecciona tu dispositivo en el diálogo y haz clic en Conectar.

Detecta un dispositivo para realizar la instalación Selecciona el dispositivo al que deseas conectarte

Una vez que el dispositivo esté conectado, deberás hacer clic en él para configurar la compilación. En el cuadro donde seleccionas un ID de compilación, elige la rama aosp-master-with-phones-throttled para que se seleccione automáticamente la imagen correcta del dispositivo que conectaste.

Selecciona un dispositivo para realizar la instalación Confirma las opciones y luego instala la compilación en el dispositivo

Haz clic en Instalar instalar la compilación en el dispositivo.

Puedes encontrar más información sobre la configuración necesaria en la documentación de Android Flash Tool. También puedes consultar la documentación de AOSP para obtener instrucciones sobre cómo compilar una imagen de HWASan desde la fuente.

Cómo compilar

Para compilar el código nativo (JNI) de la app con HWAddress Sanitizer, haz lo siguiente:

ndk-build

En el archivo Application.mk, incluye lo siguiente:

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

En el archivo build.gradle de tu módulo, incluye lo siguiente:

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 del archivo CMakeLists.txt:

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

Cómo ejecutar

Ejecuta la app como de costumbre en una imagen de Android compilada con HWASan. Cuando se detectan errores de memoria, las apps muestran una falla de SIGABRT y registran un mensaje detallado en logcat. Puedes encontrar una copia del mensaje en un archivo dentro de /data/tombstones. Se verá de la siguiente manera:

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)

El mensaje puede ir seguido de información de depuración adicional, como la lista de subprocesos activos de la aplicación, etiquetas de asignaciones de memoria cercanas, valores de registro de CPU, etcétera.