Android调试的必杀技——反汇编

在移植Android过程中会遇到很多Crash的情况,尤其是启动Android过程中。一般这些问题都可以通过 看代码能解决,当然也有一些比较“妖 娆”的问题,非常难找到头绪,在logcat日志也只会打印一些崩溃的堆栈,这些信息很难帮助我们定位问题。根据个人一个实例来介绍一下在Android 移植过程中反汇编的用法。

     首先先看一下我遇到的一个logcat关于Crash的打印信息:

I/DEBUG   ( 1417): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***







I/DEBUG ( 1417): Build fingerprint: 'generic/sdk/generic/:Eclair/ECLAIR/eng.simon.20100607.133011:eng/test-keys'







I/DEBUG ( 1417): pid: 1434, tid: 1460 >>> system_server <<<







I/DEBUG ( 1417): signal 11 (SIGSEGV), fault addr 00000000







I/DEBUG ( 1417): zr 00000000 at 00000000 v0 00007265 v1 00193228







I/DEBUG ( 1417): gp 7ef6fd60 sp 30564e90 s8 2fa07858 ra 7ef53470







I/DEBUG ( 1417): hi 0000000f lo 04444444 bva 00007265 epc 7ef534a4







I/DEBUG ( 1417): #00 pc 7ef534a4 /system/lib/libc.so







I/DEBUG ( 1417): #01 ra 7ef53470 /system/lib/libc.so







I/DEBUG ( 1417): code around pc:







I/DEBUG ( 1417): 7ef53494 afa7002c afa40030 1040000b afa50028







I/DEBUG ( 1417): 7ef534a4 8c4a0000 8c440008 8c590004 8fa2001c







I/DEBUG ( 1417): 7ef534b4 0320f809 ac4a0034 8fa9001c 8d220034







I/DEBUG ( 1417): 30564e78 00000000







I/DEBUG ( 1417): 30564e7c 7ef12af4 /system/lib/libc.so







I/DEBUG ( 1417): 30564e80 7ef6fd60







I/DEBUG ( 1417): 30564e84 00000000







I/DEBUG ( 1417): 30564ea4 7b10a8e8 /system/lib/libsqlite.so







I/DEBUG ( 1417): 30564ea8 7b10a8b4 /system/lib/libsqlite.so







I/DEBUG ( 1417): 30564ed0 7ef5d990 /system/lib/libc.so







I/DEBUG ( 1417): 30564ed4 2fa0786c







I/DEBUG ( 1417): 30564ed8 30465000







I/DEBUG ( 1417): 30564edc 00100000 [heap]







I/DEBUG ( 1417): 30564ee0 7b10a8b4 /system/lib/libsqlite.so







W/SyncManager( 1434): Updating for














new














accounts...

     通过这个log信息我们可以看到libc.so崩溃了,再研究堆栈发现是libsqilte.so引起的,那么具体是哪一个函数崩溃了呢?这里面没有信 息。另外内核加载动态库是动态加载的,就算我们反汇编出来libc.so和libsqlite.so,符号表也没有办法和log中地址对应上,除非我们能 知道内核加载libc.so和libsqlite.so的基地址,这样我们就可以通过偏移找到相应的函数了。很幸运,Android确实规定了系统中的大 部分库的内核加载地址。文件的位置在build/core下,有对应平台的map文件,比如:Arm平台文件名叫做prelink-linux- arm.map,Mips平台叫做prelink-linux-mips.map。我是在Mips平台出的问题,所以应该用prelink-linux- mips.map文件来定位。文件内容如下:

# 0x7F100000 - 0x7FFF0000 Thread 0 stack



# 0x7F000000 - 0x7F0FFFFF Linker



# 0x70000000 - 0x7EFFFFFF Prelinked System Libraries



# core system libraries



libdl.so 0x7EFF0000



libc.so 0x7EF00000



libstdc++.so 0x7EEF0000



libcutils.so 0x7EE000000用readelf -s libc.so查看库中每一个函数地址

     从这个map文件我们可以查询到每个lib库的加载基地址。比如libc.so将会被内核加载到0x7EF00000,libsqlite.so加载到 0x7B100000。我们可以对照一下Crash的log信息也对应的上,说明这个文件在Android加载过程中起了作用。

     下一步我们需要反汇编libc.so和libsqlite.so。一般交叉编译器都提供了反汇编的工具,我的mips平台提供了mips-linux-gnu-objdump命令来进行反汇编。

mips-linux-gnu-objdump -dS libc.so > libc.dump







mips-linux-gnu-objdump -dS libsqlite.so > libsqlite.dump







在Arm平台系统自带的反编译工具在android/prebuild/linux-86/toolchail/arm-abil-4.4.0/bin目录下的arm_eabi-objdump进行反汇编



arm-eabi-objdump -dS libc.so >/work/libc.dump



arm-eabi-objdump -dS libsqlite.so >/worl/libsqlite.dump







在Arm平台还提供一个命令直接定位出问题的代码



arm-eabi-addr2line -e ./symbols/system/lib/libc.so 0x10000000//-e=>fileName 0x10000000是根据栈打印出来有问题的地址



会直接定位出问题文件的行数;


     这样就可以得到libc和libsqlite的符号表。然后通过符号表,Android加载动态库的基地址,log信息就可以定位到那个函数出问题了,如 果你对对应平台汇编语言熟悉的话可以阅读汇编代码找出问题。本文就不具体讲怎样利用这个三个文件信息了。有了这个三个文件,稍一研究就可以明白怎样分析 了。

     一般情况下,Crash都不是Android源码的问题,最有可能的是内核有些模块没有编译进去。本例中就是和Mutex相关的模块没有编译进内核引起的问题。

     以上是个人摸索出来的方法,如果你有更好的方法或者我的方法有错误,请你不吝指教。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值