6.NDK Android jni开发 so库奔溃解决办法 (相机图片美化)

SO库奔溃总结方案:
1.添加日志信息
2.找到c的源代码生成带符号的so库。
3.安装bugly,分析具体那一行出了问题
4.jni异常和c++异常的基本分析和解决办法
5.从奔溃信息中可以反馈一个问题:c比较安全,比较难破解

=====================================================

 

在介绍工具之前,先简单讲一下有调试与无调试信息的两个版本 so 。 一个含有 native 代码的 app 项目的典型结构是这样的:

一般的分析崩溃日志的工具都是利用含有调试信息的 so, 结合崩溃信息,分析崩溃点在源代码中的行号。

 
通常一次编译会先生成一个有含有调试信息的 so, 路径通常是在 obj/local/ 各 abi 目录下,其中还有一些中间文件(比如.o文件);再通过对这些含有调试信息的 so 进行一次 strip , 产生对应的无调试信息 so, 放到 libs 目录下各 abi 目录中, 发布产品时,我们都是用这些 strip 后的 so。
————————————————

1.android如何编译出带符号表的.so库

如果是mk:可以直接生成2种so库
如果是cmake:debug版本就是带符号的。release就是不带符号的。
用默认的so库路径
#生成的so文件目录
#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../../../../src/main/jniLibs/armebai-v7a)
把自己生成的注释掉
 
bugly:分析有符号的so库
符号表:
 
 
VS 编写实现方法生成 dll 动态库

使用VisualStudio高效开发调试AndroidNDK

cmake编译so库。然后同时生成apk。
会发现:会先编译然后生成的apk会把so打包进去。放心好了
===========================================================================
2.so库奔溃具体行数: 定位so奔溃的行数

Android NDK墓碑/崩溃分析

 
闪退发生时在logcat中将日志过滤条件选为“No Filters”就可以看到完整的闪退日志,或者叫tombstone(墓碑)文件。
tombstone(墓碑)是当系统 crash 的时候,会保存一个 tombstone 文件到/data/tombstones目录下(Logcat中也会有相应的信息)
3.NDK安装包中提供了三个调试工具:addr2line、objdump和ndk-stack,
google官方提供的ndk-stack工具分析:
4.bugly的定位原理:ndk-stack使用:
Android ndk-stack 定位so库crash位置
如果你觉得上面的方法太麻烦的话,ndk-stack可以帮你减轻操作步聚,直接定位到代码出错的位置。
使用adb获取logcat的日志,并通过管道输出给ndk-stack分析,并指定包含符号表的so文件位置。如果程序包含多种CPU架构,需要根据手机的CPU类型,来选择不同的CPU架构目录。以armv7架构为例,执行如下命令:
 

1.运行终端。 跳转到你android sdk 目录 因为你的adb 在里面。

如 cd /Users/name/Android/adt-bundle-mac-x86_64-20131030/sdk/platform-tools 

2、找了路径正确继续下一步,./adb logcat | 你android ndk-stack所在的路径 -sym /你安卓工程.so文件所在的目录

如./adb logcat | /Users/name/Android/android-ndk-r8e/ndk-stack -sym /Users/name/test/proj.android/obj/local/armeabi

3、正确配置后会在终端出现

- waiting for device -

adb logcat | $NDK_HOME/ndk-stack -sym $PROJECT/libs/armeabi
其中,$PROJECT/libs/armeabi是so的路径。
adb logcat | $NDK_HOME/ndk-stack -sym /Users/mac/AiOpen/AiOpen/app/jni-libs/armeabi
 
<span style="color:#000000"><span style="color:#37474f">adb logcat > /Users/mac/ndk/tongue.txt</span></span>

 

 
$NDK_HOME/ndk-stack -sym /Users/mac/AiOpen/AiOpen/app/jni-libs/armeabi -dump /Users/mac/ndk/tongue.txt
可以看到具体的行数
 
 
总结:
如果是so库找不到,那么看不到详情
null指针可以
5.so库奔溃,日志种类分析:
结合signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0信息,配合崩溃信号列表:
信号 描述
SIGSEGV 内存引用无效。
SIGBUS 访问内存对象的未定义部分。
SIGFPE 算术运算错误,除以零。
SIGILL 非法指令,如执行垃圾或特权指令
SIGSYS 糟糕的系统调用
SIGXCPU 超过CPU时间限制。
SIGXFSZ 文件大小限制。

 

1、SIGSEGV 段错误

SEGV_MAPERR 要访问的地址没有映射到内存空间。 比如上面对空指针的写操作, 当指针被意外复写为一个较小的数值时。

SEGV_ACCERR 访问的地址没有权限。比如试图对代码段进行写操作。

2、SIGFPE 浮点错误,一般发生在算术运行出错时。

FPE_INTDIV 除以0

FPE_INTOVE 整数溢出

3、SIGBUS 总线错误

BUS_ADRALN 地址对齐出错。arm cpu比x86 cpu 要求更严格的对齐机制,所以在 arm cpu 机器中比较常见。

4、SIGILL 发生这种错误一般是由于某处内存被意外改写了。

ILL_ILLOPC 非法的指令操作码

ILL_ILLOPN 非法的指令操作数

5、当调用堆栈中出现 stack_chk_fail 函数时,一般是由于比如 strcpy 之类的函数调用将栈上的内容覆盖,而引起栈检查失败。

 

 
 
 

Testin崩溃分析如何帮开发者发现NDK错误

以上提到的方法,只适合在开发测试期间,如果你的应用或游戏已经上线,而用户经常反馈说崩溃、闪退,指望用户帮你收集信息定位问题几乎是不可能的。这个时候,我们就需要用其他的手段来捕获崩溃信息。

 

目前业界已经有一些公司推出了崩溃信息收集的服务,通过嵌入SDK,在程序发生崩溃时收集堆栈信息,发送到云服务平台,从而帮助开发者定位错误信息。在这方面,国内的Testin和国外的crittercism都可以提供类似服务。

 

Testin从1.4版本开始支持NDK的崩溃分析,其最新版本已升级到1.7。当程序发生NDK错误时,其内嵌的SDK会收集程序在用户手机上发生崩溃时的堆栈信息(主要就是上面我们通过logcat日志获取到的函数指针)、设备信息、线程信息等,SDK将这些信息上报至Testin云服务平台,在平台进行唯一性的处理、并可以自定义时段进行详尽的统计分析,从多维度展示程序崩溃的信息和严重程度;最新版本还支持用户自定义场景,方便开发者定位问题所在。

 

从用户手机上报的堆栈信息,Testin为NDK崩溃提供了符号化的功能,只要将我们编译过程中产生的包含符号表的so文件上传,就可以自动将函数指针地址定位到函数名称和代码行数。符号化之后,看起来就和我们前面在本地测试的结果是一样的了,一目了然。而且使用这个功能还有一个好处:这些包含符号表的so文件,在每次开发者编译之后都会改变,很有可能我们发布之后就已经变了,因为开发者会修改程序。在这样的情况下,即使我们拿到了崩溃时的堆栈信息,那也无法再进行符号化了。我们可以将这些文件上传到Testin进行符号化的工作,Testin会为我们保存和管理不同版本的so文件,确保信息不会丢失。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章