Android NDK Crash 日志抓取及定位
有人说,如何在Android Studio 可以配置日志模式,过滤NDK的crash,那么就让我们来简单看看下如何配置的。
一、Android Studio 配置 NDK Crash 过滤日志
第一步:点击下图框中部分:
第二步:选择“Edit Filter Configuration”
第三步:编译如下图中的内容,其中“Filter Name” 取一个合适的就行,但是“Log Tag” 必须为**“DEBUG”**模式,Log Level 可以为DEBUG就行。
第四步:手动出发一个NDK的crash。
第五步:查看日志,如下图。
在上图中,我们看到了关键的日志如下:
#11 pc 00032493 /data/app/com.pic.livefilters-1/lib/arm/libhairUtils.so (detectHairByOpenCV+1930)
嗯,出错的是一个叫detectHairByOpenCV的方法,但是后面的1930是什么鬼?好像不是行号,我要怎么定位呢?(PS 我也不知道这是什么鬼,之前一直被这个困扰,没找到解决方案,只能很傻的通过打印关键日志,判断出错的位置)。
so, 接下来我将介绍两个能直接定位到具体行号的方法。
二、NDK-STACK 定位 NDK Crash 位置
操作复杂吗?
so, easy。
只要执行如下代码就行:
adb logcat | ndk-stack -sym /yourProjectPath/obj/local/armeabi-v7a
PS: 必须是带symbols的so,也就是在’<PROJECT_ROOT>\app\src\main\obj\local<ABI>\下面的so’, 否则行号打印出来降是??.??
得到的日志如下图:
如图得到就是具体的类的行号。
三、使用 arm-linux-androideabi-addr2line 定位 NDK Crash
在第一章中,使用Android Studio 得到了相应的日志,我们是否可以利用下,否则Android Stuido 配置完,感觉有点鸡肋。那么这一章就可以然后利用上第一章过滤的日志。
首先,我们得配置下arm-linux-androideabi-addr2line这个工具,这个工具藏在哪里呢?
如果之前我们已经配置过NDK的环境,可以通过 which ndk-build (MAC or Linux) 得到相应地址。
大致位置如下(可供参考):
/Users/yourUsrName/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-addr2line
为了以后更方便的使用,我们可以做一个连接:
sudo ln -s arm-linux-androideabi-addr2line /usr/local/bin/addr2line
接下来,让我们开始操作吧,还记得上面我们得到的关键日志吗?忘了?没事,我再写一遍,如下:
#11 pc 00032493 /data/app/com.pic.livefilters-1/lib/arm/libhairUtils.so (detectHairByOpenCV+1930)
我们只要执行如下命令:
addr2line -f -e /yourProjectPath/src/main/obj/local/armeabi-v7a/libhairUtils.so 00032493
00032493 就是上面的指针位置,得到如下结果:
这里和使用ndk-stack命令得到结果是一致的,行号都是332,这就是引起crash的位置。让我们来看看,到底是以为上面行为引起的呢?
哦? 是创建了Object一起的? 纳尼? 创建 Object会引起什么crash? 这个时候让我们回到第一章抓取的日志,其中的message有说明为(local reference table overflow (max=512)):
哦,原来如此,是因为创建了过多的Object,导致本地变量过多,溢出了。所以降注释掉的那行代码打开就行,用完就释放掉。
总结
本文讲述了使用Android Stuido过滤日志、NDK-Stack、arm-linux-androideabi-addr2line等三种方式,其实每种都有各自的特性,用好,用顺手为重要的。