分析安卓ANR tombstone使用ndk-stack addr2line

断了今生、忘了曾经 提交于 2020-04-07 07:56:34

刷机过程中会碰到很多crash问题,此时安卓会在/data/tombstones目录下保存9个session文件,如下

root@android:/ # find . |grep tombs

./data/tombstones
./data/tombstones/tombstone_00
./data/tombstones/tombstone_01
root@android:/ #

每个tombstone文件里包含如下信息:

  1. Build fingerprint

  2. Crashed process and PIDs

  3. Terminated signal and fault address

  4. CPU registers

  5. Call stack

  6. Stack content of each call

下面讲述怎么使用ndk-stack和addr2line来跟踪tombstone文件里的错误信息:

1、安装NDK,设置环境变量

export ANDROID_NDK_PATH=/home/bytesthink/tools/android-ndk-r8d/
PATH= $ANDROID_NDK_PATH:$PATH

2、执行ndk-stack命令,其中--sym指向AOSP编译目录中符号路径 --dump指向要调试的tombstone文件

bytesthink@ubuntu:~/tools/android-ndk-r8d$ ./ndk-stack -sym ~/myrelease/symbols -dump ~/win/bytesthink/Documents/test/perform_releases/tombstone_01********** Crash dump: **********
Build fingerprint: 'version1239210121'
pid: 19135, tid: 19135, name: erviceinterface >>> com.test.powermeterserver.serviceinterface <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadd00d
Stack frame #00 pc 00072c9a /system/lib/libdvm.so (dvmAbort+170)
Stack frame #01 pc 00050f6b /system/lib/libdvm.so (ScopedCheck::checkInstanceFieldID(_jobject*, _jfieldID*)+379)
Stack frame #02 pc 0005db56 /system/lib/libdvm.so (Check_SetBooleanField(_JNIEnv*, _jobject*, _jfieldID*, unsigned char)+150)
Stack frame #03 pc 00003a93 /system/lib/libmytestt.so (Java_com_test_jni_MyLibWrapper_getMonitorSample+259)
Stack frame #04 pc 0002d850 /system/lib/libdvm.so (dvmPlatformInvoke+80)
Stack frame #05 pc 00085b48 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+648)
Stack frame #06 pc 000505db /system/lib/libdvm.so (dvmCheckCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+59)
Stack frame #07 pc 0008b96d /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+317)
Stack frame #08 pc 00170ff1 /system/lib/libdvm.so
Stack frame #09 pc 000402a6 /system/lib/libdvm.so (dvmMterpStd(Thread*)+70)
Stack frame #10 pc 0003dc14 /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+212)
Stack frame #11 pc 000b69db /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+2011)
Stack frame #12 pc 000c9f07 /system/lib/libdvm.so (Dalvik_java_lang_reflect_Method_invokeNative(unsigned int const*, JValue*)+295)
Stack frame #13 pc 00170ff1 /system/lib/libdvm.so
Stack frame #14 pc 000402a6 /system/lib/libdvm.so (dvmMterpStd(Thread*)+70)
Stack frame #15 pc 0003dc14 /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+212)
Stack frame #16 pc 000b575c /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, char*)+700)
Stack frame #17 pc 00079b8e /system/lib/libdvm.so (CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, char*)+78)
Stack frame #18 pc 0005a020 /system/lib/libdvm.so (Check_CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, char*)+432)
Stack frame #19 pc 00057c5a /system/lib/libandroid_runtime.so (_JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...)+42)
Stack frame #20 pc 00059351 /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, char const*)+945)
Stack frame #21 pc 00000fd0 /system/bin/app_process (main+528)
Stack frame #22 pc 0001a579 /system/lib/libc.so (__libc_init+89)
Stack frame #00 pc 0001ca31 /system/lib/libc.so
Stack frame #01 pc 000e66e8 /system/lib/libdvm.so (gcDaemonThread(void*)+216)
Stack frame #02 pc 00097ee0 /system/lib/libdvm.so (internalThreadStart(void*)+528)
Stack frame #03 pc 0000deb8 /system/lib/libc.so (__thread_entry+248)
Stack frame #04 pc 0001c951 /system/lib/libc.so
Stack frame #05 pc 000021e0 /dev/ashmem/dalvik-LinearAlloc (deleted)
Stack frame #06 pc 0000af42 /data/dalvik-cache/system@app@PowerManagementService.apk@classes.dex
Stack frame #00 pc 0001c05b /system/lib/libc.so
Stack frame #01 pc 0009163c /system/lib/libdvm.so (signalCatcherThreadStart(void*)+92)
Stack frame #02 pc 00097ee0 /system/lib/libdvm.so (internalThreadStart(void*)+528)
Stack frame #03 pc 0000deb8 /system/lib/libc.so (__thread_entry+248)
Stack frame #04 pc 0001c951 /system/lib/libc.so
Stack frame #05 pc 00002ff4 /system/lib/libdvm.so
Stack frame #00 pc 0001c317 /system/lib/libc.so
Stack frame #01 pc 000c012b /system/lib/libdvm.so (jdwpThreadStart(void*)+123)

通过上图发现libmytestt.so在PC地址 00003a93处崩溃;

3、使用addr2line调试

NDK和Linux上都带有这个工具,路径如下:

i686-linux-android-addr2line
NDK路径:android-ndk-r8d/toolchains/x86-4.6/prebuilt/linux-x86/bin/

可以转换个别名在全局环境中使用
alias addr2line='~/tools/android-ndk-r8d/toolchains/x86-4.6/prebuilt/linux-x86/bin/i686-linux-android-addr2line'

使用命令
bytesthink@ubuntu:~/tools/android-ndk-r8d$ addr2line -f -e ~/myrelease/symbols/system/lib/libmytestt.so 00003a93
Java_com_test_jni_MyLibWrapper_getMonitorSample
.../device/test/PRIVATE/log_infra/myservice/jni/com_test_jni_MyLibWrapper.c:189



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!