Cómo depurar la corrupción de la memoria con Address Sanitizer

En este documento, se muestra cómo habilitar herramientas especiales de depuración cuando se usa AGDE. Estas herramientas pueden ayudar con la corrupción de la memoria difìcil de diagnosticar y reemplazar errores.

HWAddress Sanitizer y Address Sanitizer

HWAddress Sanitizer (HWASan) y Address Sanitizer (ASan) son herramientas para la corrupción de la memoria que ayudan a depurarla y reemplazar errores, por ejemplo:

  • Desbordamiento y subdesbordamiento del búfer de pila
  • Desbordamiento y desbordamiento del búfer del montón
  • Uso de pila fuera de su alcance
  • Errores de liberación doble y liberación salvaje
  • Uso de pila después de la devolución (solo HWASan)

Te recomendamos que habilites HWASan o ASan solo cuando depures un problema o como parte de las pruebas automatizadas. Si bien estas herramientas tienen un buen rendimiento, su uso genera una sanción.

Comportamiento del tiempo de ejecución

Cuando se habilitan, HWASan y ASan verifican automáticamente la corrupción de la memoria de todo el tiempo de ejecución de tu app.

Si se detecta un error de memoria, la app falla con un error SIGBART (anulación de la señal) y, luego, imprime un mensaje detallado para logcat. También se escribe una copia del mensaje en un archivo dentro de /data/tombstones.

El mensaje de error es similar al siguiente:

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)

Requisitos previos

Instala una compilación HWASan del SO Android

Para usar HWASan, sigue las instrucciones de configuración en la documentación de HWASan para instalar una compilación HWASan del SO Android para dispositivos Google Pixel.

En el caso de otros dispositivos, comunícate con el fabricante para obtener una compilación HWASan del SO, si está disponible, o usa la herramienta ASan solo de software.

Usa la biblioteca C++ estándar compartida en tu proyecto

Debido a un problema conocido, ASan no es compatible con el control de excepciones de C++ cuando se usa libc++_static. Este problema no se observa cuando se utiliza libc++_shared.

HWASan tiene su propia implementación de los operadores new y delete, que no se pueden usar si la biblioteca estándar está vinculada de forma estática al proyecto.

Para cambiar este parámetro, consulta la sección Vincula la biblioteca C++ estándar de este documento.

Cómo habilitar la generación de punteros de marco

HWASan y ASan usan un desenredador rápido basado en punteros de marco para generar información de seguimiento de pila para los eventos de asignación y desasignación de memoria. Esto significa que debes habilitar la generación de punteros de marco en la configuración de tu compilador de C++ para usar estas funciones. Es decir, debes inhabilitar la optimización de la omisión de punteros de marco.

Para cambiar este parámetro, consulta la sección Habilita la generación de punteros de marco de este documento.

Configura tu proyecto de Visual Studio para usar HWASan o ASan

Habilita HWASan o ASan

Para habilitar HWASan o ASan, ve a Configuration Properties > General en Property Pages de tu proyecto.

Menú de propiedades de Solution Explorer de Visual Studio para el proyecto actual.

Figura 1: La opción Properties del proyecto en la ventana Solution Explorer de Visual Studio.

El diálogo Project Pages del proyecto que muestra las propiedades General y destaca la configuración Address Sanitizer.

Figura 2: El parámetro Address Sanitizer (ASan) en las propiedades generales del proyecto.

Para habilitar HWASan para tu proyecto, cambia el parámetro Address Sanitizer (ASan) a Hardware ASan Enabled (fsanitize=hwaddress).

Para habilitar ASan para tu proyecto, cambia el parámetro Address Sanitizer (ASan) a ASan Enabled (fsanitize=address).

Habilita la generación de punteros de marco

La generación de punteros de marco está controlada por el parámetro del compilador de C/C++ Omit Frame Pointer de que se encuentra en Property Pages de tu proyecto dentro de Configuration Properties > C/C++ > Optimization.

El diálogo Project Pages del proyecto que muestra las propiedades de Optimization de C/C++ y destaca la configuración Omit Frame Pointer.

Figura 3: Dónde encontrar el parámetro Omit Frame Pointer.

Cuando uses HWASan o ASan, establece el parámetro Omit Frame Pointer como No (-fno-omit-frame-pointer).

Vincula la biblioteca C++ estándar en el modo de biblioteca compartida

El parámetro de configuración del modo vinculador para la biblioteca C++ estándar se puede encontrar en Property Pages del proyecto dentro de Configuration Properties > General, en la sección Project Defaults.

El diálogo Project Pages del proyecto en el que se selecciona la categoría General y se destaca el parámetro Use of STL.

Figura 4: Dónde encontrar el parámetro de configuración del modo vinculador para la biblioteca C++ estándar.

Cuando uses HWASan o ASan, configura Use of STL como Use C++ Standard Libraries (.so). Este valor vincula la biblioteca C++ estándar al proyecto como una biblioteca compartida, que es necesaria para que HWASan y ASan funcionen de forma correcta.

Crea una configuración de compilación para usar Address Sanitizer

Si prefieres usar HWASan o ASan de manera transitoria, te recomendamos que no crees una nueva configuración de compilación solo para su uso. Este podría ser el caso si tu proyecto es pequeño, exploras la función o buscas la respuesta a un problema que descubres durante la prueba.

Sin embargo, si te resulta útil y planeas usarlo con regularidad, te recomendamos que crees una configuración de compilación nueva para HWASan o ASan, como se observa en la muestra Teapot. Puedes hacerlo si, por ejemplo, ejecutas Address Sanitizer con regularidad como parte de tus pruebas de unidades o durante las pruebas nocturnas de humo del juego.

Crear una configuración de compilación independiente puede ser especialmente útil si tienes un proyecto grande que consume una gran cantidad de bibliotecas de terceros diferentes que sueles vincular, de forma estática, con la biblioteca C++ estándar. La configuración de compilación dedicadas puede ayudar a garantizar que la configuración de tu proyecto siga siendo precisa en todo momento.

Para crear una configuración de compilación, desde Property Pages del proyecto, haz clic en el botón Configuration Manager… y, luego, abre el menú desplegable Active solution configuration. Luego, selecciona y crea una configuración de compilación nueva con un nombre adecuado (por ejemplo, HWASan habilitado).