设为首页 加入收藏

TOP

Android NDK中结合汇编分析Crash行为
2014-11-24 00:35:28 来源: 作者: 【 】 浏览:11
Tags:Android NDK 结合 汇编 分析 Crash 行为

1. Crash后 logcat中输出绿色信息:


05-02 10:14:37.130: I/DEBUG(1890): backtrace:
05-02 10:14:37.130: I/DEBUG(1890): #00 pc 00033fda /data/data/com.XXXXX.map/lib/libmapengine.so (TextureCache::_touchListNode(TextureCacheItem*)+25)
05-02 10:14:37.130: I/DEBUG(1890): #01 pc 0003407d /data/data/com.XXXXX.map/lib/libmapengine.so (TextureCache::getTexItem(char, char, int, int)+32)
05-02 10:14:37.130: I/DEBUG(1890): #02 pc 00032c9f /data/data/com.XXXXX.map/lib/libmapengine.so (prepareTiles(int, int, int, double)+158)
05-02 10:14:37.130: I/DEBUG(1890): #03 pc 000332cf /data/data/com.XXXXX.map/lib/libmapengine.so (nativePrepareRender+566)
05-02 10:14:37.130: I/DEBUG(1890): #04 pc 0002fb79 /data/data/com.XXXXX.map/lib/libmapengine.so (Java_com_XXXXX_map_gl_JNI_nativePrepareRender+192)
05-02 10:14:37.130: I/DEBUG(1890): #05 pc 0001de70 /system/lib/libdvm.so (dvmPlatformInvoke+112)
05-02 10:14:37.130: I/DEBUG(1890): #06 pc 0004d0c3 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+394)
05-02 10:14:37.130: I/DEBUG(1890): #07 pc 000009e0 /dev/ashmem/dalvik-jit-code-cache (deleted)


2. 找到APP中对应的SO包,获取so的汇编源码


注意编译so包时需要注释mk文件中两句:


cmd-strip = $(TOOLCHAIN_PREFIX)strip --strip-all -x $1
-fvisibility=hidden


cmd-strip 是对编译符号进行过滤的脚本,-fvisibility=hidden 是隐藏jni库内部符号表


下面的objdump工具,生成so包的汇编。
生成so包汇编代码的命令: arm-linux-androideabi-objdump.exe -dx libmapengine.so > temp.txt


3. 定位问题位置


如果幸运的话可以,logcat输出可以直接定位在函数,接下来要做的就是定位在错误的代码行数,注意指的是C/C++代码行 而不是汇编。


结合so的汇编和logcat输出,函数代码较短的话可以直接阅读arm汇编,函数长的话直接看汇编会很痛苦。


4. arm assemble的一些基本指令


ldr 从指定地址加载寄存器运算数,
str 将寄存器运算数存到指定地址,
add两个寄存器相加,
adds寄存器和数值相加,
mov寄存器之间赋值,
movs将数值赋给寄存器,
cmp为比较两个寄存器
比较条件判断:

b 表示无条件分支:http://sourceware.org/cgen/gen-doc/arm-thumb-insn.html#insn-b
bxlr 表示一个函数执行结束,参见


ARM汇编,bx lr,


bx lr


的作用等同于


mov pc,lr


即跳转到lr中存放的地址处。


那么lr存放的是什么地址呢?


lr就是连接寄存器(Link Register, LR),在ARM体系结构中LR的特殊用途有两种:一是用来保存子程序返回地址;二是当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),因此在各种异常模式下可以根据LR的值返回到异常发生前的相应位置继续执行。  


当通过BL或BLX指令调用子程序时,硬件自动将子程序返回地址保存在R14寄存器中。在子程序返回时,把LR的值复制到程序计数器PC即可实现子程序返回。


如,可以使用MOV PC, LR或者BX LR来完成子程序返回。另外,也可以在在子程序入口处使用下面的指令将LR保存到栈中



】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Android NDK空指针导致CRASH的问题 下一篇基于OpenGL实现的多段Bezier曲线..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: