Android 调试中 addr2line 命令的使用

关于调试:调试中addr2line命令的使用。
问题引出:i850的wifi定位开启后,在使用goole maps时出现rootfs重启现象,打印的log信息如下:
//////////////////////////
I/DEBUG   ( 3411): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   ( 3411): Build fingerprint: 'PROWAVE/i850/i850/:Eclair/ECLAIR/eng.zhangjiejing.20100430.113200:eng/test-keys'
I/DEBUG   ( 3411): pid: 3436, tid: 3475  >>> system_server <<<
I/DEBUG   ( 3411): signal 11 (SIGSEGV), fault addr 00000000
I/DEBUG   ( 3411):  r0 26ba7eec  r1 403f3c49  r2 e98cf6f4  r3 405e58ae
I/DEBUG   ( 3411):  r4 00000000  r5 00000000  r6 4229b6cc  r7 48fecec8
I/DEBUG   ( 3411):  r8 490ecd84  r9 48feceb4  10 48fece9c  fp 00314d30
I/DEBUG   ( 3411):  ip ad3527cd  sp 490ecd68  lr ad3527eb  pc 00000000  cpsr 00000010
I//system/bin/dhcpcd( 3673): wlan0: looping
I//system/bin/dhcpcd( 3673): wlan0: signal_fd: 4,fd:5
I/ActivityManager( 3436): Starting activity: Intent { act=Android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.android.launcher/.Launcher }
D/LocationManager( 3777): removeUpdates: listener = P.a@43da64b8
I/DEBUG   ( 3411):          #00  pc 00000000  
I/DEBUG   ( 3411):          #01  pc 000527e8  /system/lib/libandroid_runtime.so
I/DEBUG   ( 3411):          #02  pc 0000f1f4  /system/lib/libdvm.so

I/DEBUG   ( 3411):
I/DEBUG   ( 3411): code around lr:
I/DEBUG   ( 3411): ad3527d8 69e19806 694c9000 1c191c10 9b059a04
I/DEBUG   ( 3411): ad3527e8 b00247a0 46c0bd10 00017868 00006728
I/DEBUG   ( 3411): ad3527f8 4c0fb570 447c4d0f 6b2e1965 d1112e00
I/DEBUG   ( 3411):
I/DEBUG   ( 3411): stack:
I/DEBUG   ( 3411):     490ecd28  00000013  
I/DEBUG   ( 3411):     490ecd2c  ad05f661  /system/lib/libdvm.so
I/DEBUG   ( 3411):     490ecd30  410c2aec  /dalvik-LinearAlloc (deleted)
I/DEBUG   ( 3411):     490ecd34  ad0560f7  /system/lib/libdvm.so
I/DEBUG   ( 3411):     490ecd38  400292d8  /mspace/dalvik-heap/zygote/0 (deleted)
I/DEBUG   ( 3411):     490ecd3c  410c2aec  /dalvik-LinearAlloc (deleted)
I/DEBUG   ( 3411):     490ecd40  000003dc  
I/DEBUG   ( 3411):     490ecd44  ad0591f5  /system/lib/libdvm.so
I/DEBUG   ( 3411):     490ecd48  42200d44  /data/dalvik-cache/system@@classes.dex
I/DEBUG   ( 3411):     490ecd4c  42200d44  /data/dalvik-cache/system@@classes.dex
I/DEBUG   ( 3411):     490ecd50  4232b87d  /data/dalvik-cache/system@@classes.dex
I/DEBUG   ( 3411):     490ecd54  00000000  
I/DEBUG   ( 3411):     490ecd58  4264aa04  /data/dalvik-cache/system@@classes.dex
I/DEBUG   ( 3411):     490ecd5c  410c1cbc  /dalvik-LinearAlloc (deleted)
I/DEBUG   ( 3411):     490ecd60  df002777  
I/DEBUG   ( 3411):     490ecd64  e3a070ad  
I/DEBUG   ( 3411): #01 490ecd68  43160000  
I/DEBUG   ( 3411):     490ecd6c  ad05f661  /system/lib/libdvm.so
I/DEBUG   ( 3411):     490ecd70  490ecda8  
I/DEBUG   ( 3411):     490ecd74  ad00f1f8  /system/lib/libdvm.so
W/ActivityManager( 3436): Activity pause timeout for HistoryRecord{43d6cd48 com.google.android.apps.maps/com.google.android.maps.MapsActivity}
wait for fb sleep Enter
D/WifiService( 3436): releaseWifiLockLocked: WifiLock{NetworkLocationProvider type=2 binder=android.os.Binder@43bfb998}
binder: release 3436:3560 transaction 22233 in, still active
binder: send failed reply for transaction 22233 to 3777:3777
I/DEBUG   ( 3411): debuggerd committing suicide to free the zombie!
I/DEBUG   ( 3855): debuggerd: Apr 14 2010 14:24:22
I/ServiceManager( 2066): service 'usagestats' died
I/ServiceManager( 2066): service 'account' died
//////////////////////////
注意到红色部分,这就是程序执行时的栈!显然第一个pc指针的值为0,也就是pc指针为空,这就是问题之所在,接下来就是要定位这个问题,上边说了,这里是程序执行时的栈,那么#01  pc 000527e8  /system/lib/libandroid_runtime.so   这个地址就是我们要找的问题的范围,因为显然是后者先入栈的,所以显然前者包含于后者,那么通过如下命令用地址定位一下源码的位置:
cpp@cpp:~/r7_0422$ ../gcc-4.1.2-glibc-2.5-nptl-3/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-addr2line -e out/target/product/i850/symbols /system/lib/libandroid_runtime.so 000527e8
frameworks/base/core/jni/android_location_GpsLocationProvider.cpp:397
cpp@cpp:~/r7_0422$


看到源码的397行是一个函数,那么000527e8就是这个函数的入口地址了。继而,pc 000000 对应的调用就应该在该函数内部,看到该函数内部只是做了对另一个函数指针的调用而已,所以我们可以断定这个函数指针的值为空,显然调用一个空的指针函数是错误的。所以需要给这个函数指针在早些时候赋值一下问题就可以解决了!


关于addr2line的一点补充:如果可执行文件中没有包括调试符号,您将获得??:0 作为响应。  还有在linux中的readelf命令可以读取可执行文件的相关信息,比如有一个可执行文件 aa.elf  则可以这么使用: readelf    -h      aa.elf 参数-h读取可执行文件的head信息。  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwxwwj.html