Cuando la herramienta HWASan detecta un error de memoria, el proceso finaliza con abort() y se imprime un informe en stderr y logcat. Al igual que todas las fallas nativas en Android, los errores de HWASan se encuentran en /data/tombstones.
Informe de ejemplo
En comparación con las fallas nativas normales, HWASan incluye información adicional en el campo Abort message cerca de la parte superior de la lápida. Este es un ejemplo de falla basada en el montón. Para obtener información sobre los errores de pila, consulta la nota de las secciones específicas de la pila.
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** Build fingerprint: 'google/flame_hwasan/flame:Tiramisu/MASTER/7956676:userdebug/dev-keys' Revision: 'DVT1.0' ABI: 'arm64' Timestamp: 2019-04-24 01:13:22+0000 pid: 11154, tid: 11154, name: sensors@1.0-ser >>> /vendor/bin/hw/android.hardware.sensors@1.0-service <<< signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr -------- Abort message: '==9569==ERROR: HWAddressSanitizer: tag-mismatch on address 0x00433ae20045 at pc 0x00623ae2a9cc READ of size 1 at 0x00433ae20045 tags: 5b/83 (ptr/mem) in thread T0 #0 0x7240450c68 (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) #1 0x723dffd490 (/vendor/lib64/sensors.ssc.so+0x34490) #2 0x723e0126e0 (/vendor/lib64/sensors.ssc.so+0x496e0) [...] [0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5 Cause: use-after-free 0x00433ae20045 is located 5 bytes inside of 10-byte region [0x00433ae20040,0x00433ae2004a) freed by thread T0 here: #0 0x72404d1b18 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0x10b18) #1 0x723af23040 (/vendor/lib64/libgralloccore.so+0x5040) #2 0x723af23fa4 (/vendor/lib64/libgralloccore.so+0x5fa4) [...] previously allocated here: #0 0x72404ce554 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0xd554) #1 0x7240115654 (/apex/com.android.runtime/lib64/bionic/libc.so+0x43654) #2 0x7240450ac8 (/system/lib64/vndk-sp-R/libcutils.so+0x8ac8) [...] hwasan_dev_note_heap_rb_distance: 1 1023 hwasan_dev_note_num_matching_addrs: 0 hwasan_dev_note_num_matching_addrs_4b: 0 Thread: T0 0x006a00002000 stack: [0x007fc1064000,0x007fc1864000) sz: 8388608 tls: [0x00737702ffc0,0x007377033000) Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x006f33ae2000: 08 00 08 00 [83] 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. =>0x006f33ae2000: 72 .. d0 .. [..] .. .. .. .. .. .. .. .. .. .. .. 0x006f33ae2010: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags Registers where the failure occurred (pc 0x00623ae2a9cc): x0 0000007fc18623ec x1 5b0000433ae20045 x2 0000000000000013 x3 ffffffffffffffff x4 ffffffffffffffff x5 0000007fc1861da3 x6 6f7420676e696f47 x7 45522061206f6420 x8 0000000000000000 x9 0200006b00000000 x10 00000007fc18623f x11 5b0000433ae20040 x12 6f64206f7420676e x13 0a44414552206120 x14 0000000000000010 x15 ffffffffffffffff x16 000000737169ac94 x17 0000000000000007 x18 0000007377bd8000 x19 0000007fc1862498 x20 0200006b00000000 x21 0000007fc18624a8 x22 0000000000000001 x23 0000000000000000 x24 0000000000000000 x25 0000000000000000 x26 0000000000000000 x27 0000000000000000 x28 0000000000000000 x29 0000007fc1862410 x30 000000623ae2a9d0 sp 0000007fc18623d0 SUMMARY: HWAddressSanitizer: tag-mismatch (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) [ … regular crash dump follows …]
Esto es similar a un informe de AddressSanitizer. A diferencia de esos, casi todos los errores de HWASan son errores de falta de coincidencia de etiquetas, es decir, un acceso a la memoria en el que una etiqueta de puntero no coincide con la etiqueta de memoria correspondiente. Esto podría ser cualquiera de los siguientes:
- Acceso fuera de límites en la pila o el montón
- Error de uso después de la liberación en el montón
- Error de uso después de la devolución en la pila
Secciones
A continuación, se explica cada una de las secciones del informe de HWASan.
Error de acceso
Contiene información sobre el acceso incorrecto a la memoria, incluido lo siguiente:
- Tipo de acceso (
READen comparación conWRITE) - Tamaño de acceso (cantidad de bytes a los que se intentó acceder)
- Número de subprocesos del acceso
- Etiquetas de puntero y memoria (para depuración avanzada)
Seguimiento de pila de acceso
Seguimiento de pila del acceso incorrecto a la memoria. Consulta Simbolización para simbolizar.
Causa
La posible causa del acceso incorrecto. Si hay varios candidatos, se enumeran en orden de probabilidad descendente. Precede a la información detallada sobre la posible causa. HWASan puede diagnosticar las siguientes causas:
- Uso después de la liberación
- Falta de coincidencia de etiquetas de pila, que puede ser uso de pila después de la devolución, uso de pila después del alcance o fuera de límites
- Desbordamiento de búfer de montón
- Desbordamiento global
Información de la memoria
Describe lo que HWASan sabe sobre la memoria a la que se accede y puede variar según el tipo de error:
| Tipo de error | Causa | Formato del informe |
|---|---|---|
| Falta de coincidencia de etiquetas | Uso después de la liberación | Usa este formato de informe:<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
| Desbordamiento de búfer de montón | Ten en cuenta que también puede ser un desabastecimiento.<address> is located N bytes to the right of M-byte region [<start>, <end>) allocated here: |
|
| Falta de coincidencia de etiquetas de pila | Los informes de pila no diferencian entre el desbordamiento o el desabastecimiento y los errores de uso después de la devolución. Además, para encontrar la asignación de pila que es la fuente del error, se requiere un paso de simbolización sin conexión. Consulta Cómo interpretar los informes de pila reports. | |
| Liberación no válida | Uso después de la liberación | Un error de liberación doble. Si esto sucede cuando se cierra el proceso, puede significar un
incumplimiento de ODR.
<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
| No se puede describir la dirección | Ya sea una liberación salvaje (liberación de memoria que no se había asignado antes) o una liberación doble después de que la memoria asignada se expulsó del búfer libre de HWASan. | |
| 0x... es la memoria de sombra de HWAsan | Una liberación salvaje, ya que la app intentaba liberar memoria interna de HWASan. |
Seguimiento de pila de desasignación
Seguimiento de pila de la ubicación en la que se desasignó la memoria. Solo está presente para errores de uso después de la liberación o de liberación no válida. Consulta Simbolización para simbolizar.
Seguimiento de pila de asignación
Seguimiento de pila de la ubicación en la que se asignó la memoria. Consulta Simbolización para simbolizar.
Información de depuración avanzada
El informe de HWASan también incluye información de depuración avanzada, que incluye (en orden):
- La lista de subprocesos en el proceso
- La lista de subprocesos en el proceso
- El valor de las etiquetas de memoria cerca de la memoria con errores
- El volcado de los registros en el punto de acceso a la memoria
Volcado de etiquetas de memoria
Puedes usar el volcado de etiquetas de memoria para buscar asignaciones de memoria cercanas con la misma etiqueta que la etiqueta de puntero. Estas etiquetas pueden apuntar a un acceso fuera de límites con un desplazamiento grande. Una etiqueta corresponde a 16 bytes de memoria; la etiqueta de puntero son los 8 bits superiores de la dirección. El volcado de etiquetas de memoria puede dar sugerencias. Por ejemplo, el siguiente es un desbordamiento de búfer a la derecha:
tags: ad/5c (ptr/mem) [...] Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: 0e 0e 0e 57 20 20 20 20 20 2e 5e 5e 5e 5e 5e b5 =>0x006f33ae2000: f6 f6 f6 f6 f6 4c ad ad ad ad ad ad [5c] 5c 5c 5c 0x006f33ae2010: 5c 04 2e 2e 2e 2e 2e 2f 66 66 66 66 66 80 6a 6a Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: ab 52 eb .. .. .. .. .. .. .. .. .. .. .. .. .. =>0x006f33ae2000: .. .. .. .. .. .. .. .. .. .. .. .. [..] .. .. .. 0x006f33ae2010: .. 5c .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Ten en cuenta la ejecución de 6 × 16 = 96 bytes de etiquetas ad a la izquierda que coinciden con la etiqueta de puntero.
Si el tamaño de una asignación no es un múltiplo de 16, el resto del tamaño se almacena como la
etiqueta de memoria y la etiqueta se almacena como una etiqueta de gránulo
corto. En el ejemplo anterior, justo después de la asignación en negrita etiquetada como ad, tenemos una asignación de 5 × 16 + 4 = 84 bytes de la etiqueta 5c.
Una etiqueta de memoria cero (por ejemplo, tags: ad/00 (ptr/mem)) indica un
error de uso de pila después de la devolución.
Volcado de registros
El volcado de registros en los informes de HWASan corresponde a la instrucción que realizó el acceso no válido a la memoria. Este volcado está seguido de otro volcado de registros del controlador de señales normal de Android. Ignora el segundo volcado, ya que se tomó cuando HWASan llamó a
abort() y no es relevante para el error.
Simbolización
Para obtener nombres de funciones y números de línea en seguimientos de pila (y obtener nombres de variables para errores de uso después del alcance), se necesita un paso de simbolización sin conexión.
Primera configuración: instala llvm-symbolizer
Para simbolizar, tu sistema debe tener instalado llvm-symbolizer y ser accesible desde $PATH. En Debian, puedes instalarlo con sudo apt install llvm.
Obtén archivos de símbolos
Para la simbolización, requerimos archivos binarios sin procesar que contengan símbolos. Su ubicación depende del tipo de compilación:
- Para las compilaciones locales, los archivos de símbolos se encuentran en
out/target/product/<product>/symbols/. - Para las compilaciones de AOSP (por ejemplo, escritas en la memoria flash desde
Android Flash Tool), las
compilaciones se encuentran en Android CI. En los artefactos de la compilación, hay un archivo
${PRODUCT}-symbols-${BUILDID}.zip. - Para las compilaciones internas de tu organización, consulta la documentación de tu organización para obtener ayuda para obtener archivos de símbolos.
Simbolizar
hwasan_symbolize --symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash
Cómo interpretar los informes de pila
Para los errores que ocurren con las variables de pila, el informe de HWASan contiene detalles como este:
Cause: stack tag-mismatch Address 0x007d4d251e80 is located in stack of thread T64 Thread: T64 0x0074000b2000 stack: [0x007d4d14c000,0x007d4d255cb0) sz: 1088688 tls: [0x007d4d255fc0,0x007d4d259000) Previously allocated frames: record_addr:0x7df7300c98 record:0x51ef007df3f70fb0 (/apex/com.android.art/lib64/libart.so+0x570fb0) record_addr:0x7df7300c90 record:0x5200007df3cdab74 (/apex/com.android.art/lib64/libart.so+0x2dab74) [...]
Para ayudarte a comprender los errores de pila, HWASan realiza un seguimiento de los marcos de pila anteriores. HWASan no los transforma en contenido comprensible para el usuario en el informe de errores y requiere un paso de simbolización adicional.
Incumplimientos de ODR
Algunos errores de uso después de la liberación que informa HWASan pueden indicar un incumplimiento de la regla de una definición (ODR). Un incumplimiento de ODR ocurre cuando la misma variable se define varias veces en el mismo programa. Esto también significa que la variable se destruye varias veces, lo que puede provocar el error de uso después de la liberación.
Después de la simbolización, los incumplimientos de ODR muestran un error de uso después de la liberación con __cxa_finalize, tanto en la pila de acceso no válida como en la pila liberada aquí. La pila asignada anteriormente aquí contiene __dl__ZN6soinfo17call_constructorsEv y debe apuntar a la ubicación de tu programa que define la variable más arriba en la pila.
Se puede incumplir la ODR si se usan bibliotecas estáticas. Si una biblioteca estática que define un global de C++ está vinculada a varias bibliotecas compartidas o ejecutables, pueden existir varias definiciones del mismo símbolo en el mismo espacio de direcciones, lo que provoca un error de ODR.
Solución de problemas
En esta sección, se describen algunos errores y cómo abordarlos.
HWAddressSanitizer no puede describir la dirección con más detalle
A veces, HWASan puede quedarse sin espacio para obtener información sobre las asignaciones de memoria anteriores. En ese caso, el informe contiene solo un seguimiento de pila para el acceso inmediato a la memoria, seguido de una nota:
HWAddressSanitizer can not describe address in more detail.
En algunos casos, puedes resolver este problema ejecutando la prueba varias veces. Otra opción es aumentar el tamaño del historial de HWASan. Puedes hacerlo de forma global en build/soong/cc/sanitize.go (busca hwasanGlobalOptions) o en el entorno de tu proceso (prueba adb shell echo $HWASAN_OPTIONS para ver la configuración actual).
Este error también puede ocurrir si la memoria a la que se accede no está asignada o asignada por un asignador que no reconoce HWASan. En este caso, la etiqueta mem que aparece en el encabezado de la falla suele ser 00. Si tienes acceso a la lápida completa, puede ser útil consultar el volcado de mapas de memoria para averiguar a qué asignación (si corresponde) pertenece la dirección.
Error anidado en el mismo subproceso
Esto significa que hubo un error mientras se generaba el informe de fallas de HWASan. Por lo general, esto se debe a un error en el entorno de ejecución de HWASan. Registra un error y proporciona instrucciones para reproducir el problema si es posible.