热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

androidaddr2line用法,Androidstudio中NDK开发(四)——使用addr2line分析Crash日志

一、前言在NDK开发中经常会出现应用Crash的情况,而JNI层的报错信息,不像Java层报错信息那样可以直接在日志中看到错误的行数,JN

一、前言

在NDK开发中经常会出现应用Crash的情况,而JNI层的报错信息,不像Java层报错信息那样可以直接在日志中看到错误的行数,JNI层中出现的错误直接看根本定位不到错误的位置。通常来说,JNI报的基本都是堆栈信息,需要NDK的一些工具进行地址转换,转换后即可看到错误的位置。这些地址转换的工具有addr2line、ndk-stack等,我比较喜欢addr2line,平时也用这个工具进行调试。

二、分析

错误信息如下:

A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

A/DEBUG: Build fingerprint: 'xiaomi/mido/mido:7.0/NRD90M/V10.1.1.0.NCFCNFI:user/release-keys'

A/DEBUG: Revision: '0'

A/DEBUG: ABI: 'arm'

A/DEBUG: pid: 29290, tid: 29290, name: e.hasee.ndkdemo >>> com.example.hasee.ndkdemo <<<

A/DEBUG: signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------

A/DEBUG: r0 00000000 r1 0000726a r2 00000006 r3 00000008

A/DEBUG: r4 f6cbc590 r5 00000006 r6 f6cbc538 r7 0000010c

A/DEBUG: r8 12e45dc0 r9 f3f88000 sl ff90e8ec fp f3f88000

A/DEBUG: ip 00000058 sp ff90e5f8 lr f5c3a2c7 pc f5c3cb48 cpsr 200f0010

A/DEBUG: backtrace://堆栈信息&#xff0c;只需要关注这部分就好

A/DEBUG: #00 pc 00049b48 /system/lib/libc.so (tgkill&#43;12)

A/DEBUG: #01 pc 000472c3 /system/lib/libc.so (pthread_kill&#43;34)

A/DEBUG: #02 pc 0001d565 /system/lib/libc.so (raise&#43;10)

A/DEBUG: #03 pc 000190b1 /system/lib/libc.so (__libc_android_abort&#43;34)

A/DEBUG: #04 pc 00017114 /system/lib/libc.so (abort&#43;4)

A/DEBUG: #05 pc 0009063f /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so (_ZN7GSMutex4LockEv&#43;90)

A/DEBUG: #06 pc 00090837 /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so (_ZN11GSAutoMutexC1ER7GSMutex&#43;10)

A/DEBUG: #07 pc 0004b4d7 /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so (_ZN12GSGB28181SDK9CSipStack18GetHistoryRegisterEv&#43;34)

A/DEBUG: #08 pc 0004b60b /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so (_ZN12GSGB28181SDK9CSipStack13SendRegistMsgERK16_Stru_Regist_MsgjPc&#43;58)

A/DEBUG: #09 pc 000033a3 /data/app/com.example.hasee.ndkdemo-2/lib/arm/libnative-lib.so (Java_com_example_hasee_ndkdemo_NDKUtil_agentRegister&#43;686)

1、先提取backtrace部分

上面的这些报错信息里面&#xff0c;backtrace部分显示的是错误的堆栈信息&#xff0c;所以我们只需要关注 backtrace部分就可以了。

提取后如下所示&#xff1a;

A/DEBUG: backtrace:

A/DEBUG: #00 pc 00049b48 /system/lib/libc.so (tgkill&#43;12)

A/DEBUG: #01 pc 000472c3 /system/lib/libc.so (pthread_kill&#43;34)

A/DEBUG: #02 pc 0001d565 /system/lib/libc.so (raise&#43;10)

A/DEBUG: #03 pc 000190b1 /system/lib/libc.so (__libc_android_abort&#43;34)

A/DEBUG: #04 pc 00017114 /system/lib/libc.so (abort&#43;4)

A/DEBUG: #05 pc 0009063f /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so (_ZN7GSMutex4LockEv&#43;90)

A/DEBUG: #06 pc 00090837 /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so (_ZN11GSAutoMutexC1ER7GSMutex&#43;10)

A/DEBUG: #07 pc 0004b4d7 /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so (_ZN12GSGB28181SDK9CSipStack18GetHistoryRegisterEv&#43;34)

A/DEBUG: #08 pc 0004b60b /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so (_ZN12GSGB28181SDK9CSipStack13SendRegistMsgERK16_Stru_Regist_MsgjPc&#43;58)

A/DEBUG: #09 pc 000033a3 /data/app/com.example.hasee.ndkdemo-2/lib/arm/libnative-lib.so (Java_com_example_hasee_ndkdemo_NDKUtil_agentRegister&#43;686)

2、提取对应so库的信息

可以看到每一行最后面都跟着“xxx.so”信息

“#00” 至 “#04” 部分后面的都是 “/system/lib/libc.so” &#xff0c;这些都是系统的库&#xff0c;这个我们不需要管&#xff1b;

“#05” 至 “#09” 部分后面的so库都是我自己的&#xff0c;这些才是我们需要定位的部分。

“/data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so” // 引入的第三方so库

“/data/app/com.example.hasee.ndkdemo-2/lib/arm/libnative-lib.so ”// 编译生成的so库

将“#05” 至 “#09” 部分提取出来&#xff0c;如下所示&#xff1a;

A/DEBUG: #05 pc 0009063f /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so (_ZN7GSMutex4LockEv&#43;90)

A/DEBUG: #06 pc 00090837 /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so (_ZN11GSAutoMutexC1ER7GSMutex&#43;10)

A/DEBUG: #07 pc 0004b4d7 /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so (_ZN12GSGB28181SDK9CSipStack18GetHistoryRegisterEv&#43;34)

A/DEBUG: #08 pc 0004b60b /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so (_ZN12GSGB28181SDK9CSipStack13SendRegistMsgERK16_Stru_Regist_MsgjPc&#43;58)

A/DEBUG: #09 pc 000033a3 /data/app/com.example.hasee.ndkdemo-2/lib/arm/libnative-lib.so (Java_com_example_hasee_ndkdemo_NDKUtil_agentRegister&#43;686)

3、提取错误地址

剩下到的这几行中&#xff0c;重点看 “pc” 后面的十六进制数&#xff0c;这些是对应so库中的具体错误信息地址&#xff0c;这些地址才是我们最终需要转换的对象。为了更直观的展示&#xff0c;我把前面的“A/DEBUG” 和 “pc” 两个标签去掉&#xff0c;剩下行号还有地址以及so库部分提取出来。

提取如下所示&#xff1a;

#050009063f /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so

#0600090837 /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so

#070004b4d7 /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so

#080004b60b /data/app/com.example.hasee.ndkdemo-2/lib/arm/libthird.so

#09000033a3 /data/app/com.example.hasee.ndkdemo-2/lib/arm/libnative-lib.so

上面就是最终我们需要关注的部分&#xff0c;有了十六进制地址值以及后面的so库&#xff0c;下面我们就可以使用addr2line进行地址转换了。

三、使用addr2line对地址进行转换

1、addr2line工具的路径放在

" ${NDK} / toolchains / ${ABI} / prebuilt / windows-x86_64 / bin / "下

${NDK} // 你的NDK解压包路径

${ABI} // 你的调试设备的CPU架构,通常来说实体机一般都是对应 arm-linux-androideabi

2、Terminal中转换地址的命令

arm-linux-androideabi-addr2line -C -f -e ${SOPATH} ${Address}

-C -f //打印错误行数所在的函数名称

-e //打印错误地址的对应路径及行数

${SOPATH} //so库路径

${Address}//需要转换的堆栈错误信息地址&#xff0c;可以添加多个&#xff0c;但是中间要用空格隔开

四、例子

对上面最终提取的错误信息(“#05 – #09”)中的堆栈地址进行转换

1、首先找到自己的so库路径

对于“#05” 至 “#08” 部分的地址&#xff0c;我对应的so库路径为

F:/Android/workspace/NDKDemo/app/src/main/jniLibs/armeabi-v7a/libthird.so

对于“#09”行中的地址&#xff0c;我对应的so库为&#xff1a;

F:/Android/workspace/NDKDemo/app/build/intermediates/cmake/debug/obj/armeabi-v7a/libnative-lib.so

2、在Terminal中输入命令

对于“#05” 至 “#08” 部分的地址&#xff0c;我输入的命令为&#xff1a;

arm-linux-androideabi-addr2line -C -f -e F:/Android/workspace/NDKDemo/app/src/main/jniLibs/armeabi-v7a/libthird.so 0009063f 00090837 0004b4d7 0004b60b

对于“#09”行中的地址&#xff0c;我输入的命令为&#xff1a;

arm-linux-androideabi-addr2line -C -f -e F:/Android/workspace/NDKDemo/app/build/intermediates/cmake/debug/obj/armeabi-v7a/libnative-lib.so 000033a3

注意&#xff1a;

1)我这里已经将addr2line配置到环境变量中&#xff0c;所以可以直接使用arm-linux-androideabi-addr2line命令。如果没有配置的话&#xff0c;记得要加上自己的完整路径,否则会出现Terminal报错&#xff1a;

“&#39;arm-linux-androideabi-addrline2&#39; 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。”

2)要看清楚后面的so库&#xff0c;我这里第三方的so库和我自己的编译打包的so库都有报错地址信息&#xff0c;所以转换地址的时候&#xff0c;要注意地址后面对应的是哪个so库&#xff0c;不然的话会转换失败&#xff0c;转换的地址显示为 " ? ? 0 “(一个so库的错误地址信息跑到另外一个so库去查&#xff0c;当然查不到&#xff0c;除非两个错误位置在两个so库中的堆栈地址相同&#xff0c;查不到的时候&#xff0c;就会输出” ? ? 0 ")这个问题也困扰了我一个上午&#xff0c;要特别注意。

3)libnative-lib.so是我自己打包编译的库&#xff0c;自己打包编译的so库可以在Project视图的

" ./app/build/intermediates/cmake/debug/obj/&{ABI}/ " 路径下找到

d9e29a950ef039e68c00ba1e4741225e.png

3、效果

第三方libthird.so库的显示信息

d2204f6f7cbff92f2e079d9352092cfc.png

自己编译的libnatve-lib.so库的显示信息

1e30259e8916056b4a2948b97bac2455.png

点击一下转换后的地址就可以跳转到错误的位置了。

如有错误&#xff0c;欢迎指正&#xff0c;虚心学习&#xff01;



推荐阅读
author-avatar
穿靴子的猫
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有