Android Native crash日志分析,androidcrash
在Android应用crash的类型中,native类型crash应该是比较难的一种了,因为大家接触的少,然后相对也要多转几道工序,所有大部分对这个都比较生疏。虽然相关文章也有很多了,但是我在刚开始学的过程中还是遇到一些问题,下面一一记录,以便将来翻阅。
分析native crash 日志需要几个东西:
log
native crash的日志都是从一行星号(*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***)开始,这行星号也是ndk-stack工具用来查找native crash的标志。一个native crash日志例子:
1 04-16 11:18:00.323 26512 26512 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 2 04-16 11:18:00.324 26512 26512 F DEBUG : Build fingerprint: 'nubia/NX531J/NX531J:7.1.1/NMF26F/nubia04130311:user/release-keys' 3 04-16 11:18:00.324 26512 26512 F DEBUG : Revision: '0' 4 04-16 11:18:00.324 26512 26512 F DEBUG : ABI: 'arm' 5 04-16 11:18:00.324 26512 26512 F DEBUG : pid: 26452, tid: 26491, name: Thread-4 >>> com.willhua.opencvstudy <<< 6 04-16 11:18:00.324 26512 26512 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xc8080000 7 04-16 11:18:00.324 26512 26512 F DEBUG : r0 c807a400 r1 c7e80000 r2 00000069 r3 00000069 8 04-16 11:18:00.324 26512 26512 F DEBUG : r4 caa4ca9c r5 007e9000 r6 00000964 r7 c69838f8 9 04-16 11:18:00.324 26512 26512 F DEBUG : r8 00005c00 r9 00017002 sl 001fa400 fp cac6ec00 10 04-16 11:18:00.324 26512 26512 F DEBUG : ip e71aac64 sp c69838e8 lr caa8e949 pc caa8e97c cpsr 800f0030 11 04-16 11:18:00.326 26512 26512 F DEBUG : 12 04-16 11:18:00.326 26512 26512 F DEBUG : backtrace: 13 04-16 11:18:00.326 26512 26512 F DEBUG : #00 pc 0004097c /data/app/com.willhua.opencvstudy-1/lib/arm/libOpenCV.so (_Z14darkGrayThreadPv+179) 14 04-16 11:18:00.326 26512 26512 F DEBUG : #01 pc 000475d3 /system/lib/libc.so (_ZL15__pthread_startPv+22) 15 04-16 11:18:00.326 26512 26512 F DEBUG : #02 pc 00019d3d /system/lib/libc.so (__start_thread+6)
带symbols的so文件
对于比如手机公司的开发人员来说,一般来说出问题的so对应的带symbols的so都在out/target/product/<model_name>/symbols/system/lib/下面,而对于常见的使用AndroidStudio开发的单个应用来说,其对应的带symbols的在<PROJECT_ROOT>\app\src\main\obj\local\<ABI>\下面的so,而不能是\app\src\main\libs\<ABI>的,这里面的是不包含symbols信息的,拿这个去分析,输出的结果就是“??:?”。其实这两个so的体积对比也是很明显的的,在我的应用中,前一个带symbols的so的体积为7M多,而后一个只有2M。
分析工具
- addr2line:用来分析单个pc地址对应的源码行数,比如示例log中的第13行中的#00 pc 0004097c,0004097c就是crash时pc调用的堆栈地址,用这个地址就可以分析出对应在源码中的行数;
- objdump:用来把相应的so变成汇编语言的asm文件,然后根据地址信息(比如0004097c)就可以找到更加详细的相关函数信息;
- ndk-stack:用来把log信息全部翻译成更加详细的带源码行数信息的log,相当于是在整个crash堆栈信息都执行addr2line命令。
对于使用linux系统作为开发环境的,linux就自带addr2line命令。而对于笔者这种使用Windows的,在sdk中安装了NDK之后,在ndk中就带有这些工具。
比如addr2line工具在:sdk\ndk-bundle\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin下面,同时这个bin下面包含很多其他工具,比如objdump,readelf等;
ndk-stack工具则在sdk\ndk-bundle下面;
关于这些工具的具体使用,在https://www.oschina.net/question/2241352_213433这篇文章中讲的很详细,我也就不再重复。
但是提醒一点:crash log与对应的so一定要对应起来。即错误的情况是:你拿了一份旧的log,然后你修改了so相关的源码,然后编译出来了新的so,你拿着这个新的so以及旧log中的地址去让addr2line等分析,那肯定是是得不到正确的结果的。
刚刚提到的那篇文章讲的很详细,为了避免以后找不到所以我就把它复制到这里。
/****************************************************************************************************************************************/
转自:https://www.oschina.net/question/2241352_213433
Android NDK是什么,为什么我们要用NDK?
Android NDK 是在SDK前面又加上了“原生”二字,即Native Development Kit,因此又被Google称为“NDK”。众所周知,Android程序运行在Dalvik虚拟机中,NDK允许用户使用类似C / C++之类的原生代码语言执行部分程序。NDK包括了:
- 从C / C++生成原生代码库所需要的工具和build files。
- 将一致的原生库嵌入可以在Android设备上部署的应用程序包文件(application packages files,即.apk文件)中。
- 支持所有未来Android平台的一些列原生系统头文件和库
为何要用到NDK?概括来说主要分为以下几种情况:
- 代码的保护,由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。
- 在NDK中调用第三方C/C++库,因为大部分的开源库都是用C/C++代码编写的。
- 便于移植,用C/C++写的库可以方便在其他的嵌入式平台上再次使用。
Android JNI是什么?和NDK是什么关系?
Java Native Interface(JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI是本地编程接口,它使得在 Java 虚拟机(VM) 内部运行的 Java 代码能够与用其它编程语言(如 C、C++和汇编语言)编写的应用程序和库进行交互操作。
简单来说,可以认为NDK就是能够方便快捷开发.so文件的工具。JNI的过程比较复杂,生成.so需要大量操作,而NDK就是简化了这个过程。
NDK的异常会不会导致程序Crash,NDK的常见的有哪些类型异常?
NDK编译生成的.so文件作为程序的一部分,在运行发生异常时同样会造成程序崩溃。不同于Java代码异常造成的程序崩溃,在NDK的异常发生时,程序在Android设备上都会立即退出,即通常所说的闪退,而不会弹出“程序xxx无响应,是否立即关闭”之类的提示框。
NDK是使用C/C++来进行开发的,熟悉C/C++的程序员都知道,指针和内存管理是最重要也是最容易出问题的地方,稍有不慎就会遇到诸如内存无效访问、无效对象、内存