ndk-stack

La herramienta ndk-stack te permite simbolizar seguimientos de pila a partir de adb logcat o una tombstone en /data/tombstones/. Reemplaza las direcciones dentro de una biblioteca compartida por el elemento <source-file>:<line-number> correspondiente de tu código fuente, lo que facilita la depuración.

Por ejemplo, traduce algo como lo siguiente:

I/DEBUG   (   31): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (   31): Build fingerprint: 'generic/google_sdk/generic/:2.2/FRF91/43546:eng/test-keys'
I/DEBUG   (   31): pid: 351, tid: 351  >>> /data/local/ndk-tests/crasher <<<
I/DEBUG   (   31): signal 11 (SIGSEGV), fault addr 0d9f00d8
I/DEBUG   (   31):  r0 0000af88  r1 0000a008  r2 baadf00d  r3 0d9f00d8
I/DEBUG   (   31):  r4 00000004  r5 0000a008  r6 0000af88  r7 00013c44
I/DEBUG   (   31):  r8 00000000  r9 00000000  10 00000000  fp 00000000
I/DEBUG   (   31):  ip 0000959c  sp be956cc8  lr 00008403  pc 0000841e  cpsr 60000030
I/DEBUG   (   31):          #00  pc 0000841e  /data/local/ndk-tests/crasher
I/DEBUG   (   31):          #01  pc 000083fe  /data/local/ndk-tests/crasher
I/DEBUG   (   31):          #02  pc 000083f6  /data/local/ndk-tests/crasher
I/DEBUG   (   31):          #03  pc 000191ac  /system/lib/libc.so
I/DEBUG   (   31):          #04  pc 000083ea  /data/local/ndk-tests/crasher
I/DEBUG   (   31):          #05  pc 00008458  /data/local/ndk-tests/crasher
I/DEBUG   (   31):          #06  pc 0000d362  /system/lib/libc.so
I/DEBUG   (   31):

y genera un resultado más fácil de leer:

********** Crash dump: **********
Build fingerprint: 'generic/google_sdk/generic/:2.2/FRF91/43546:eng/test-keys'
pid: 351, tid: 351  >>> /data/local/ndk-tests/crasher <<<
signal 11 (SIGSEGV), fault addr 0d9f00d8
Stack frame #00  pc 0000841e  /data/local/ndk-tests/crasher : Routine zoo in /tmp/foo/crasher/jni/zoo.c:13
Stack frame #01  pc 000083fe  /data/local/ndk-tests/crasher : Routine bar in /tmp/foo/crasher/jni/bar.c:5
Stack frame #02  pc 000083f6  /data/local/ndk-tests/crasher : Routine my_comparison in /tmp/foo/crasher/jni/foo.c:9
Stack frame #03  pc 000191ac  /system/lib/libc.so
Stack frame #04  pc 000083ea  /data/local/ndk-tests/crasher : Routine foo in /tmp/foo/crasher/jni/foo.c:14
Stack frame #05  pc 00008458  /data/local/ndk-tests/crasher : Routine main in /tmp/foo/crasher/jni/main.c:19
Stack frame #06  pc 0000d362  /system/lib/libc.so

Uso

Para usar ndk-stack, primero necesitas un directorio que contenga versiones sin eliminación de contenido de las bibliotecas compartidas de tu app. Si usas ndk-build, estas bibliotecas compartidas sin eliminación de contenido se encuentran en $PROJECT_PATH/obj/local/<abi>, donde <abi> es la ABI de tu dispositivo.

Para una compilación del complemento de Android para Gradle (AGP), las bibliotecas sin quitarle el encabezado estarán en <project-path>/build/intermediates/cxx/<build-type>/<hash>/obj/<abi>, donde <project-path> es el directorio del proyecto de AGP que contiene el módulo que intentas simbolizar (de forma predeterminada, es app), <build-type> es el nombre del tipo de compilación de CMake o ndk-build (como RelWithDebInfo, Release, Debug, etcétera). <hash> es arbitrario y <abi> es la ABI de tu dispositivo.

Existen dos maneras de usar la herramienta. Puedes proporcionar el texto de logcat como una entrada directa al programa. Por ejemplo:

adb logcat | $NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi-v7a

También puedes usar la opción -dump para especificar el logcat como un archivo de entrada. Por ejemplo:

adb logcat > /tmp/foo.txt
$NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi-v7a -dump foo.txt

Cuando comienza a analizar el resultado del logcat, la herramienta busca una línea inicial de asteriscos. Por ejemplo:

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

Nota: Cuando copies o pegues seguimientos, no olvides esta línea. De lo contrario, ndk-stack no funcionará correctamente.

Más información

Google Play usa ndk-stack a fin de simbolizar seguimientos de pila a las apps nativas en Google Play Console. Si quieres obtener información para habilitar esto en tu app en un entorno de producción, consulta cómo incluir un archivo de símbolos de depuración nativo para tu app en Google Play Console.