Android NDK tombstone分析工具
在Andoird Native库发生异常的时候,Linux会发生不同级别的sig,来结构相关进程的运行,同时会产生tombstone trace文件用于记录发生崩溃寄存器和堆栈的状态。
这里面的涉及的知识点很多,但该文主要是介绍一下这种情况debug的工具stack.py。
1,keypoint
a,Android sig/进程间通讯
b,Linux 内存管理/ 用户空间和内核空间
c,Arm汇编
d,Android库的链接Linker
2,tombstone的结构大概如下
1 *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 2 Build fingerprint: 'MBX/k200/k200:4.4.2/KOT49H/20140717:user/test-keys' 3 Revision: '11' 4 pid: 455, tid: 486, name: InputDispatcher >>> system_server <<< 5 signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00290238 6 r0 00290008 r1 00000230 r2 00000003 r3 00290008 7 r4 64a42042 r5 677d9eac r6 677f16e8 r7 000003f2 8 r8 41656d40 r9 00000002 sl 00000000 fp 68088ca0 9 ip 000000f2 sp 68088b38 lr 00000000 pc 4165a9d8 cpsr 200b0010 10 d0 677d9fd84b000000 d1 626e402800010000 11 d2 002e00640069006f d3 00650074006e0069 12 d4 006c0061006e0072 d5 006c006f0070002e 13 d6 002e007900630069 d7 00790065004b0049 14 d8 0000000000000000 d9 0000000000000000 15 d10 0000000000000000 d11 0000000000000000 16 d12 0000000000000000 d13 0000000000000000 17 d14 0000000000000000 d15 0000000000000000 18 d16 3d5e000000000000 d17 3d5e000000000000 19 d18 408f400000000000 d19 41168cb340000000 20 d20 4020f5c28f5c28f6 d21 408a800000000000 21 d22 40b4c3e100000000 d23 3ff0000000000000 22 d24 41f2a05f20000000 d25 40b3880000000000 23 d26 408a800000000000 d27 4053000000000000 24 d28 0000000000000000 d29 0000000000000000 25 d30 0100010001000100 d31 0100010001000100 26 scr 20000010 27 28 backtrace: 29 #00 pc 000219d8 /system/lib/libdvm.so 30 #01 pc 0002dfa0 /system/lib/libdvm.so (dvmMterpStd(Thread*)+76) 31 #02 pc 0002b638 /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184) 32 #03 pc 00060581 /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+336) 33 #04 pc 0004c9cd /system/lib/libdvm.so 34 #05 pc 00009de9 /system/lib/libandroid_servers.so 35 #06 pc 0000a2b7 /system/lib/libandroid_servers.so (android::NativeInputManager::interceptKeyBeforeDispatching(android::sp<android::InputWindowHandle> const&, android::KeyEvent const*, unsigned int)+58) 36 #07 pc 00020a49 /system/lib/libinputservice.so (android::InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(android::InputDispatcher::CommandEntry*)+60) 37 #08 pc 00022487 /system/lib/libinputservice.so (android::InputDispatcher::runCommandsLockedInterruptible()+58) 38 #09 pc 0002571b /system/lib/libinputservice.so (android::InputDispatcher::dispatchOnce()+50) 39 #10 pc 0001fb61 /system/lib/libinputservice.so (android::InputDispatcherThread::threadLoop()+8) 40 #11 pc 0000e9ed /system/lib/libutils.so (android::Thread::_threadLoop(void*)+104) 41 #12 pc 0004d4b1 /system/lib/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+68) 42 #13 pc 0000e58f /system/lib/libutils.so 43 #14 pc 0000d200 /system/lib/libc.so (__thread_entry+72) 44 #15 pc 0000d398 /system/lib/libc.so (pthread_create+240) 45 其中backtrace就是当时system_server接收到signal 11时,堆栈调用的信息,这些信息很重要,能帮忙还原发生异常的现场。signal 11的定义在这里$android_root/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6/sysroot/usr/include/bits/signum.h
1 /* Signals. */ 2 #define SIGHUP 1 /* Hangup (POSIX). */ 3 #define SIGINT 2 /* Interrupt (ANSI). */ 4 #define SIGQUIT 3 /* Quit (POSIX). */ 5 #define SIGILL 4 /* Illegal instruction (ANSI). */ 6 #define SIGTRAP 5 /* Trace trap (POSIX). */ 7 #define SIGABRT 6 /* Abort (ANSI). */ 8 #define SIGIOT 6 /* IOT trap (4.2 BSD). */ 9 #define SIGBUS 7 /* BUS error (4.2 BSD). */ 10 #define SIGFPE 8 /* Floating-point exception (ANSI). */ 11 #define SIGKILL 9 /* Kill, unblockable (POSIX). */ 12 #define SIGUSR1 10 /* User-defined signal 1 (POSIX). */ 13 #define SIGSEGV 11 /* Segmentation violation (ANSI). */ 14 #define SIGUSR2 12 /* User-defined signal 2 (POSIX). */ 15 #define SIGPIPE 13 /* Broken pipe (POSIX). */ 16 #define SIGALRM 14 /* Alarm clock (POSIX). */ 17 #define SIGTERM 15 /* Termination (ANSI). */ 18 #define SIGSTKFLT 16 /* Stack fault. */ 19 #define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ 20 #define SIGCHLD 17 /* Child status has changed (POSIX). */ 21 #define SIGCONT 18 /* Continue (POSIX). */ 22 #define SIGSTOP 19 /* Stop, unblockable (POSIX). */ 23 #define SIGTSTP 20 /* Keyboard stop (POSIX). */ 24 #define SIGTTIN 21 /* Background read from tty (POSIX). */ 25 #define SIGTTOU 22 /* Background write to tty (POSIX). */ 26 #define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */ 27 #define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */ 28 #define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ 29 #define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ 30 #define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ 31 #define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */ 32 #define SIGPOLL SIGIO /* Pollable event occurred (System V). */ 33 #define SIGIO 29 /* I/O now possible (4.2 BSD). */ 34 #define SIGPWR 30 /* Power failure restart (System V). */ 35 #define SIGSYS 31 /* Bad system call. */ 36 #define SIGUNUSED 31 stack.py工具就是要把backtrace通过addr2line工具一次性把15个addr对应到代码。
先看一下帮助,在主机上执行
python stack.py --help
1 build/core/envsetup.mk:10: /version_defaults.mk: No such file or directory 2 build/core/envsetup.mk:115: /product_config.mk: No such file or directory 3 make: *** No rule to make target `/product_config.mk'. Stop. 4 5 usage: stack.py [options] [FILE] 6 7 --symbols-dir=path 8 the path to a symbols dir, such as =/tmp/out/target/product/dream/symbols 9 10 --symbols-zip=path 11 the path to a symbols zip file, such as =dream-symbols-12345.zip 12 13 --auto 14 attempt to: 15 1) automatically find the build number in the crash 16 2) if it's an official build, download the symbols 17 from the build server, and use them 18 19 FILE should contain a stack trace in it somewhere 20 the tool will find that and re-print it with 21 source files and line numbers. If you don't 22 pass FILE, or if file is -, it reads from 23 stdin. tombstone生成文件一般位于手机中/data/tombstone/文件夹下面,工具使用如下:
1 python stack.py --symbols-dir=out/target/product/$yourproduct/symbols/ tombstone-00
1 Searching for native crashes in tombstone-0718 2 Reading symbols from out/target/product/k200/symbols/ 3 pid: 455, tid: 486, name: InputDispatcher >>> system_server <<< 4 signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00290238 5 r0 00290008 r1 00000230 r2 00000003 r3 00290008 6 r4 64a42042 r5 677d9eac r6 677f16e8 r7 000003f2 7 r8 41656d40 r9 00000002 sl 00000000 fp 68088ca0 8 ip 000000f2 sp 68088b38 lr 00000000 pc 4165a9d8 9 10 Stack Trace: 11 ADDR FUNCTION FILE:LINE 12 000219d8 dalvik_inst /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/dalvik/vm/mterp/out/InterpAsm-armv7-a-neon.S:7358 13 0002dfa0 dvmMterpStd(Thread*) /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/dalvik/vm/mterp/Mterp.cpp:105 14 0002b638 dvmInterpret(Thread*, Method const*, JValue*) /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/dalvik/vm/interp/Interp.cpp:1961 15 00060581 dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list) /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/dalvik/vm/interp/Stack.cpp:526 16 0004c9cd CallLongMethodV /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/dalvik/vm/Jni.cpp:1968 17 00009de9 _JNIEnv::CallLongMethod(_jobject*, _jmethodID*, ...) /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/libnativehelper/include/nativehelper/jni.h:625 18 0000a2b7 android::NativeInputManager::interceptKeyBeforeDispatching(android::sp<android::InputWindowHandle> const&, android::KeyEvent const*, unsigned int) /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/frameworks/base/services/jni/com_android_server_input_InputManagerService.cpp:938 19 00020a49 android::InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(android::InputDispatcher::CommandEntry*) /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/frameworks/base/services/input/InputDispatcher.cpp:3478 20 00022487 android::InputDispatcher::runCommandsLockedInterruptible() /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/frameworks/base/services/input/InputDispatcher.cpp:615 (discriminator 3) 21 0002571b android::InputDispatcher::dispatchOnce() /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/frameworks/base/services/input/InputDispatcher.cpp:237 22 0001fb61 android::InputDispatcherThread::threadLoop() /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/frameworks/base/services/input/InputDispatcher.cpp:4484 23 0000e9ed android::Thread::_threadLoop(void*) /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/system/core/libutils/Threads.cpp:770 24 0004d4b1 android::AndroidRuntime::javaThreadShell(void*) /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/frameworks/base/core/jni/AndroidRuntime.cpp:1000 25 0000e58f thread_data_t::trampoline(thread_data_t const*) /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/system/core/libutils/Threads.cpp:95 26 0000d200 __thread_entry /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/bionic/libc/bionic/pthread_create.cpp:105 27 0000d398 pthread_create /mnt/nfsroot/gangfeng.xu/work/kk-amlogic-dev/bionic/libc/bionic/pthread_create.cpp:224 很方便吧,不用一个一个的去找了。
工具链接如下:
stack.py
refer to:
https://sites.google.com/a/itspaclub.com/www/android-debug/7-how-to-debug-native-code
http://stackoverflow.com/questions/5106581/how-to-get-longer-stacktrace-tombstone-from-android
http://blog.csdn.net/helldevil/article/details/6682211
0 0