A ferramenta ndk-stack
permite simbolizar stack traces de
adb logcat
ou um
Tombstone em /data/tombstones/
. Ela substitui qualquer endereço dentro de uma biblioteca compartilhada pelo <source-file>:<line-number>
correspondente do seu código-fonte, facilitando a depuração.
Por exemplo, ela converte algo como:
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):
em uma saída mais legível:
********** 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
, primeiro você precisa de um diretório que contenha versões sem remoção de conteúdo das
bibliotecas compartilhadas do seu app. Se você usa ndk-build
, essas bibliotecas compartilhadas
sem remoção de conteúdo podem ser encontradas em $PROJECT_PATH/obj/local/<abi>
, em que <abi>
é a
ABI do seu dispositivo.
Para um build do Plug-in do Android para Gradle (AGP), as bibliotecas sem remoção de conteúdo estarão em
<project-path>/build/intermediates/cxx/<build-type>/<hash>/obj/<abi>
, em que
<project-path>
é o diretório do projeto do AGP que contém o módulo
que você está tentando simbolizar (por padrão, é app
), <build-type>
é o
nome do tipo de build do CMake ou do ndk-build (como RelWithDebInfo
, Release
,
Debug
etc.). <hash>
é arbitrário, e <abi>
é a ABI do dispositivo.
Há duas formas de usar a ferramenta. Você pode inserir texto do logcat como entrada direta no programa. Por exemplo:
adb logcat | $NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi-v7a
Você também pode usar a opção -dump
para especificar o logcat como um arquivo de entrada. Por exemplo:
adb logcat > /tmp/foo.txt $NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi-v7a -dump foo.txt
Quando a análise da saída do logcat for iniciada, a ferramenta buscará uma linha de asteriscos inicial. Exemplo:
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Observação: ao copiar/colar traces, não se esqueça dessa linha.
Caso contrário, ndk-stack
não funcionará corretamente.
Mais informações
O Google Play usa ndk-stack
para simbolizar stack traces para apps
nativos no Google Play Console. Para saber como ativar esse recurso em seu
app em um ambiente de produção, veja como
incluir um arquivo de símbolos de depuração nativo
para o app no Google Play Console.