Comprensión de los informes HWASan

Cuando la herramienta HWASan detecta un error de memoria, el proceso finaliza con abort() y se imprime un informe en stderr y logcat. Como todos los bloqueos nativos en Android, los errores de HWASan se pueden encontrar en /data/tombstones .

En comparación con los bloqueos nativos regulares, HWASan incluye información adicional en el campo "Mensaje de cancelación" cerca de la parte superior de la lápida. Vea un bloqueo basado en montón de muestra a continuación (para errores de pila, consulte la nota a continuación para las secciones específicas de pila).

Informe de ejemplo

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
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: '

[...]

[0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5








[ … regular crash dump follows …]

Esto es muy similar a un informe de AddressSanitizer . A diferencia de estos, casi todos los errores de HWASan son "etiquetas no coincidentes", es decir, un acceso a la memoria en el que una etiqueta de puntero no coincide con la etiqueta de memoria correspondiente. Este podría ser uno de

  • acceso fuera de los límites en la pila o el montón
  • usar después de liberar en el montón
  • usar después de regresar a la pila

Secciones

A continuación, se incluye una explicación de cada una de las secciones del informe HWASan:

error de acceso

Contiene información sobre el acceso incorrecto a la memoria, que incluye:

  • Tipo de acceso ("LEER" frente a "ESCRIBIR")
  • Tamaño de acceso (a cuántos bytes se intentó acceder)
  • Número de hilo del acceso
  • Puntero y etiquetas de memoria (para depuración avanzada)

Seguimiento de la pila de acceso

Seguimiento de la pila del acceso a memoria incorrecto. Vea la sección de Simbolización para simbolizar.

Causa

La posible causa del mal acceso. 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 libre
  • stack-tag-mismatch: esto puede ser stack use-after-return/use after-scope, o fuera de los 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 diferir según el tipo de error.

Tipo de error Causa Formato de informe
etiqueta no concuerda uso después de libre
<address> is located N bytes inside of M-byte region [<start>, <end>)
  freed by thread T0 here:
desbordamiento de búfer de montón Tenga en cuenta que esto también puede ser un subdesbordamiento.
<address> is located N bytes to the right of M-byte region [<start>, <end>)
  allocated here:
discrepancia de etiqueta de pila Los informes de pila no diferencian entre errores de desbordamiento/subdesbordamiento y uso tras devolución. Además, para encontrar la asignación de pila que es el origen del error, se requiere un paso de simbolización fuera de línea. Consulte la sección Comprensión de los informes de pila a continuación.
libre de inválidos uso después de libre Este es un error doble libre. Si esto sucede durante el cierre del proceso, esto puede significar una infracción de ODR .
<address> is located N bytes inside of M-byte region [<start>, <end>)
  freed by thread T0 here:
no puedo describir la dirección Una liberación salvaje (sin memoria que no se había asignado antes) o una liberación doble después de que la memoria asignada se desalojó del búfer libre de HWASan.
0x... es memoria de sombra HWAsan. Esta es definitivamente una forma gratuita, ya que la aplicación intentaba liberar memoria interna de HWASan.

Rastreo de pila de desasignación

Seguimiento de la pila de dónde se desasignó la memoria. Solo presente para errores use-after-free o invalid-free. Ver la sección de Simbolización para simbolizar.

Seguimiento de la pila de asignación

Seguimiento de la pila de dónde se asignó la memoria. Ver la sección de Simbolización para simbolizar.

Información de depuración avanzada

El informe HWASan también presenta información de depuración avanzada, que incluye (en orden):

  1. La lista de subprocesos en el proceso.
  2. La lista de subprocesos en el proceso.
  3. El valor de las etiquetas de memoria cerca de la memoria que falla
  4. El volcado de los registros en el punto de acceso a la memoria.

Volcado de etiquetas de memoria

El volcado de memoria de etiquetas se puede utilizar para buscar asignaciones de memoria cercanas con la misma etiqueta que la etiqueta del puntero. Estos podrían apuntar a un acceso fuera de los límites con un gran desplazamiento. Una etiqueta corresponde a 16 bytes de memoria; la etiqueta del puntero son los 8 bits superiores de la dirección. El volcado de memoria de etiquetas puede dar pistas, 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  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
(tenga en cuenta la ejecución de 6 × 16 = 96 bytes de etiquetas de "anuncio" a la izquierda que coinciden con la etiqueta del puntero).

Si el tamaño de una asignación no es un múltiplo de 16, el resto del tamaño se almacenará como etiqueta de memoria y la etiqueta se almacenará como una etiqueta de gránulos cortos . En el ejemplo anterior, justo después del anuncio etiquetado de asignación en negrita, tenemos una asignación de 5 × 16 + 4 = 84 bytes de la etiqueta 5c.

Una etiqueta de memoria cero (p. ej., tags: ad/ 00 (ptr/mem) ) generalmente indica un error de uso después de la devolución de la pila.

volcado de registro

El volcado de registro en los informes de HWASan corresponde a la instrucción real que realizó el acceso a la memoria no válido. Le sigue otro volcado de registro del controlador de señal normal de Android; ignore el segundo , se toma 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 fuera de línea.

Configuración por primera vez: instale llvm-symbolizer

Para simbolizar, su sistema debe tener llvm-symbolizer instalado y accesible desde $PATH. En Debian, puede instalarlo usando sudo apt install llvm .

Obtener archivos de símbolos

Para la simbolización, requerimos binarios sin despojar que contengan símbolos. Dónde se pueden encontrar depende del tipo de compilación:

Para compilaciones locales , los archivos de símbolos se pueden encontrar en out/target/product/<product>/symbols/ .

Para compilaciones AOSP (por ejemplo, flasheadas desde Flashstation ), las compilaciones se pueden encontrar en Android CI . En los "Artefactos" para la compilación, habrá un archivo `${PRODUCT}-symbols-${BUILDID}.zip`.

Para compilaciones internas de su organización, consulte la documentación de su organización para obtener ayuda para obtener archivos de símbolos.

Simbolizar

hwasan_symbolize –-symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash

Comprender los informes de pila

Para los errores que ocurren con las variables de pila, el informe HWASan contendrá 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 permitir que se entiendan los errores de pila, HWASan realiza un seguimiento de los marcos de pila que ocurrieron en el pasado. Actualmente, HWASan no transforma esto en contenido comprensible para los humanos en el informe de errores y requiere un paso de simbolización adicional.

Violaciones ODR

Algunos errores de uso después de liberación informados por HWASan también pueden indicar una violación de la regla de definición única (ODR). Una infracción 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 generar el error de uso después de la liberación.

Después de la simbolización, las infracciones de ODR muestran un uso posterior a la liberación con __cxa_finalize , tanto en la pila de acceso no válido como en la pila "liberada aquí". La pila "previamente asignada aquí" contiene __dl__ZN6soinfo17call_constructorsEv y debe apuntar a la ubicación en su programa que define la variable más arriba en la pila.

Una de las razones por las que se puede violar la ODR es cuando se utilizan bibliotecas estáticas. Si una biblioteca estática que define un C++ global está vinculada a varias bibliotecas compartidas o ejecutables, es posible que varias definiciones del mismo símbolo terminen existiendo en el mismo espacio de direcciones, lo que provocará un error ODR.

Solución de problemas

"HWAddressSanitizer no puede describir la dirección con más detalle".

A veces, HWASan puede quedarse sin espacio para obtener información sobre asignaciones de memoria anteriores. En ese caso, el informe contendrá 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, esto se puede resolver ejecutando la prueba varias veces. Otra opción es aumentar el tamaño del historial de HWASan. Esto se puede hacer globalmente en build/soong/cc/sanitize.go (busque hwasanGlobalOptions ), o en su entorno de proceso (pruebe adb shell echo $HWASAN_OPTIONS para ver la configuración actual).

"error anidado en el mismo hilo"

Esto significa que hubo un error al generar el informe de bloqueo de HWASan. Esto generalmente se debe a un error en el tiempo de ejecución de HWASan, informe un error y proporcione instrucciones sobre cómo reproducir el problema si es posible.