Android NDK Crash 日志抓取及定位
有人說,如何在Android Studio 可以配置日志模式,過濾NDK的crash,那麼就讓我們來簡單看看下如何配置的。
一、Android Studio 配置 NDK Crash 過濾日志
第一步:點選下圖框中部分:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX1xWbZxmVIVWdsdkY2R2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39TOxYzM1ATM1EzMwUDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
第二步:選擇“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等三種方式,其實每種都有各自的特性,用好,用順手為重要的。