native调用栈分析

1.  addr2line命令

addr2line -h 可以查看命令使用帮助:

一般命令使用方式:addr2line -e 可执行程序文件 -f -C  address

比如下面一个调用栈打印:

01-01 08:00:08.030  2981  2981 D surfaceflinger start: #00 pc 00002875  /system/bin/surfaceflinger (main+636)
01-01 08:00:08.030  2981  2981 D surfaceflinger start: #01 pc 00088161  /system/lib/libc.so (__libc_init+48)
01-01 08:00:08.030  2981  2981 D surfaceflinger start: #02 pc 000025b7  /system/bin/surfaceflinger (_start_main+38)
01-01 08:00:08.030  2981  2981 D surfaceflinger start: #03 pc 00000306  <anonymous:f266e000> 

这是在surfaceflinger模块的启动入口:main_surfaceflinger.cpp的main方法中打印的,我们可以用addr2line命令看下第3行和第2行对应的代码行, 第3行的system/bin/surfaceflinger是一个可执行程序, 第2行的system/lib/libc.so是一个so库, Android系统源码编译后生成的带调试符号的可执行程序文件或so文件都在out/target/product/xxx/symbols目录下,为了防止addr2line命令参数过长,我们可以先进入该目录下。

第3行的地址是0x000025b7, 命令执行结果如下:

 第2行的地址是0x00088161, 命令执行结果如下:

我们可以分别看下这2个执行结果所对应的代码:

bionic/libc/arch-common/bionic/crtbegin.c

 39 __used static void _start_main(void* raw_args) {
 40   structors_array_t array;
 41   array.preinit_array = &__PREINIT_ARRAY__;
 42   array.init_array = &__INIT_ARRAY__;
 43   array.fini_array = &__FINI_ARRAY__;
 44 
 45   __libc_init(raw_args, NULL, &main, &array);
 46 }

bionic/libc/bionic/libc_init_dynamic.cpp

104 // This function is called from the executable's _start entry point
105 // (see arch-$ARCH/bionic/crtbegin_dynamic.S), which is itself
106 // called by the dynamic linker after it has loaded all shared
107 // libraries the executable depends on.
108 //
109 // Note that the dynamic linker has also run all constructors in the
110 // executable at this point.
111 __noreturn void __libc_init(void* raw_args,
112                             void (*onexit)(void) __unused,
113                             int (*slingshot)(int, char**, char**),
114                             structors_array_t const * const structors) {
115   BIONIC_STOP_UNWIND;
116 
117   KernelArgumentBlock args(raw_args);
118 
119   // Several Linux ABIs don't pass the onexit pointer, and the ones that
120   // do never use it.  Therefore, we ignore it.
121 
122   // The executable may have its own destructors listed in its .fini_array
123   // so we need to ensure that these are called when the program exits
124   // normally.
125   if (structors->fini_array) {
126     __cxa_atexit(__libc_fini,structors->fini_array,NULL);
127   }
128 
129   exit(slingshot(args.argc, args.argv, args.envp));
130 }

目前还看不太懂。。。但看注释意思是正确的。

2)使用ndk-stack工具

工具是在android ndk开发包中, 可以从下面2个网址下载:

https://developer.android.google.cn/ndk/downloads/

https://developer.android.google.cn/ndk/downloads/older_releases

我是在linux环境使用的, 下载的linux-x86_64版本,然后上传到ubuntu虚拟机某一目录后解压,解压后可以用下面的命令加入到环境变量中, 环境变量要持久化的话需要将这行命令追加到~/.bashrc文件:

export PATH=$PATH:/home/xxuser/android-ndk-r21

ndk-stack命令使用方式很简单,-h可以看到使用帮助:

-sym或--sym 指定符号文件路径, -i或-dump或--dump指定输入文件,也就是调用栈文件,可以直接是tomstones文件,也可以通过管道|将logcat与ndk-stack命令连接使用。

下面是一个使用示例:

crash.txt文件:

01-01 08:00:42.270  4570  4570 F libc    : Fatal signal 6 (SIGABRT), code -6 (SI_TKILL) in tid 4570 (main), pid 4570 (main)
01-01 08:00:42.315  4605  4605 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-01 08:00:42.315  4605  4605 F DEBUG   : Build fingerprint: 'tcl/tcl_m7642/tcl_m7642:9/PPR2.180905.006.A1/xiang10_chen08311137:userdebug/dev-keys'
01-01 08:00:42.315  4605  4605 F DEBUG   : Revision: '1234'
01-01 08:00:42.315  4605  4605 F DEBUG   : ABI: 'arm'
01-01 08:00:42.315  4605  4605 F DEBUG   : pid: 4570, tid: 4570, name: main  >>> zygote <<<
01-01 08:00:42.315  4605  4605 F DEBUG   : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
01-01 08:00:42.315  4605  4605 F DEBUG   : Abort message: 'jni_internal.cc:616] JNI FatalError called: RegisterNatives failed for 'android/view/SurfaceControl'; aborting...'
01-01 08:00:42.316  4605  4605 F DEBUG   :     r0  00000000  r1  000011da  r2  00000006  r3  00000008
01-01 08:00:42.316  4605  4605 F DEBUG   :     r4  000011da  r5  000011da  r6  ffe021bc  r7  0000010c
01-01 08:00:42.316  4605  4605 F DEBUG   :     r8  00000000  r9  f1f10720  r10 ffe023c8  r11 f1e6a65e
01-01 08:00:42.316  4605  4605 F DEBUG   :     ip  ffe02158  sp  ffe021a8  lr  f48a5f69  pc  f489ddba
01-01 08:00:42.348  4605  4605 F DEBUG   :
01-01 08:00:42.348  4605  4605 F DEBUG   : backtrace:
01-01 08:00:42.348  4605  4605 F DEBUG   :     #00 pc 0001cdba  /system/lib/libc.so (abort+58)
01-01 08:00:42.348  4605  4605 F DEBUG   :     #01 pc 0034db8f  /system/lib/libart.so (art::Runtime::Abort(char const*)+910)
01-01 08:00:42.348  4605  4605 F DEBUG   :     #02 pc 000071b3  /system/lib/libbase.so (android::base::LogMessage::~LogMessage()+494)
01-01 08:00:42.348  4605  4605 F DEBUG   :     #03 pc 00265a53  /system/lib/libart.so (art::JNI::FatalError(_JNIEnv*, char const*)+122)
01-01 08:00:42.348  4605  4605 F DEBUG   :     #04 pc 00001f35  /system/lib/libnativehelper.so (jniRegisterNativeMethods+120)
01-01 08:00:42.348  4605  4605 F DEBUG   :     #05 pc 000a2645  /system/lib/libandroid_runtime.so (android::register_android_view_SurfaceControl(_JNIEnv*)+20)
01-01 08:00:42.348  4605  4605 F DEBUG   :     #06 pc 0006efa9  /system/lib/libandroid_runtime.so (android::AndroidRuntime::startReg(_JNIEnv*)+64)
01-01 08:00:42.348  4605  4605 F DEBUG   :     #07 pc 0006ed0f  /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, android::Vector<android::String8> const&, bool)+214)
01-01 08:00:42.348  4605  4605 F DEBUG   :     #08 pc 00001989  /system/bin/app_process32 (main+728)
01-01 08:00:42.348  4605  4605 F DEBUG   :     #09 pc 00088161  /system/lib/libc.so (__libc_init+48)
01-01 08:00:42.348  4605  4605 F DEBUG   :     #10 pc 0000166f  /system/bin/app_process32 (_start_main+38)
01-01 08:00:42.348  4605  4605 F DEBUG   :     #11 pc 00000306  <anonymous:f5ba3000>

ndk-stack执行结果:

user@SZ0000303:~/samba/9652_A200/Android9.0_beta_IP_svn1640_20200514/out/target/product/tcl_m7642/symbols$ ndk-stack -sym ./system/lib -i ~/android-ndk-r21/crash.txt 
********** Crash dump: **********
Build fingerprint: 'tcl/tcl_m7642/tcl_m7642:9/PPR2.180905.006.A1/xiang10_chen08311137:userdebug/dev-keys'
Abort message: 'jni_internal.cc:616] JNI FatalError called: RegisterNatives failed for 'android/view/SurfaceControl'; aborting...'
#00 0x0001cdba /system/lib/libc.so (abort+58)
                                    inline_tgkill(int, int, int)
                                    bionic/libc/bionic/abort.cpp:43:3
                                    abort
                                    bionic/libc/bionic/abort.cpp:68:0
#01 0x0034db8f /system/lib/libart.so (art::Runtime::Abort(char const*)+910)
                                      art::Runtime::Abort(char const*)
                                      art/runtime/runtime.cc:588:3
#02 0x000071b3 /system/lib/libbase.so (android::base::LogMessage::~LogMessage()+494)
                                       std::__1::function<void (char const*)>::operator()(char const*) const
                                       external/libcxx/include/functional:1916:12
                                       android::base::LogMessage::~LogMessage()
                                       system/core/base/logging.cpp:458:0
#03 0x00265a53 /system/lib/libart.so (art::JNI::FatalError(_JNIEnv*, char const*)+122)
                                      art::JNI::FatalError(_JNIEnv*, char const*)
                                      art/runtime/jni_internal.cc:616:5
#04 0x00001f35 /system/lib/libnativehelper.so (jniRegisterNativeMethods+120)
                                               _JNIEnv::FatalError(char const*)
                                               libnativehelper/include_jni/jni.h:541:7
                                               jniRegisterNativeMethods
                                               libnativehelper/JNIHelp.cpp:155:0
#05 0x000a2645 /system/lib/libandroid_runtime.so (android::register_android_view_SurfaceControl(_JNIEnv*)+20)
                                                  android::RegisterMethodsOrDie(_JNIEnv*, char const*, JNINativeMethod const*, int)
                                                  frameworks/base/core/jni/core_jni_helpers.h:70:15
                                                  android::register_android_view_SurfaceControl(_JNIEnv*)
                                                  frameworks/base/core/jni/android_view_SurfaceControl.cpp:1049:0
#06 0x0006efa9 /system/lib/libandroid_runtime.so (android::AndroidRuntime::startReg(_JNIEnv*)+64)
                                                  android::register_jni_procs(android::RegJNIRec const*, unsigned int, _JNIEnv*)
                                                  frameworks/base/core/jni/AndroidRuntime.cpp:1337:13
                                                  android::AndroidRuntime::startReg(_JNIEnv*)
                                                  frameworks/base/core/jni/AndroidRuntime.cpp:1538:0
#07 0x0006ed0f /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, android::Vector<android::String8> const&, bool)+214)
                                                  android::AndroidRuntime::start(char const*, android::Vector<android::String8> const&, bool)
                                                  frameworks/base/core/jni/AndroidRuntime.cpp:1103:9
#08 0x00001989 /system/bin/app_process32 (main+728)
#09 0x00088161 /system/lib/libc.so (__libc_init+48)
                                    __libc_init
                                    bionic/libc/bionic/libc_init_dynamic.cpp:129:8
#10 0x0000166f /system/bin/app_process32 (_start_main+38)
#11 0x00000306 <anonymous:f5ba3000>
Crash dump is completed

ndk-stack对输入有要求,调用栈前必须有如下一行*号分隔符才可以:

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

 

ndk-stack工具也可以用于app的native crash分析,用法一样,只是此时的符号文件路径可能是类似 app/build/intermediates/cmake/debug/obj/x86这种的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值