天天看點

Android NDK Crash 日志抓取及定位Android NDK Crash 日志抓取及定位

Android NDK Crash 日志抓取及定位

有人說,如何在Android Studio 可以配置日志模式,過濾NDK的crash,那麼就讓我們來簡單看看下如何配置的。

一、Android Studio 配置 NDK Crash 過濾日志

第一步:點選下圖框中部分:

Android NDK Crash 日志抓取及定位Android NDK Crash 日志抓取及定位

第二步:選擇“Edit Filter Configuration”

第三步:編譯如下圖中的内容,其中“Filter Name” 取一個合适的就行,但是“Log Tag” 必須為**“DEBUG”**模式,Log Level 可以為DEBUG就行。

Android NDK Crash 日志抓取及定位Android NDK Crash 日志抓取及定位

第四步:手動出發一個NDK的crash。

第五步:檢視日志,如下圖。

Android NDK Crash 日志抓取及定位Android 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’, 否則行号列印出來降是??.??

得到的日志如下圖:

Android NDK Crash 日志抓取及定位Android NDK Crash 日志抓取及定位

如圖得到就是具體的類的行号。

三、使用 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 就是上面的指針位置,得到如下結果:

Android NDK Crash 日志抓取及定位Android NDK Crash 日志抓取及定位

這裡和使用ndk-stack指令得到結果是一緻的,行号都是332,這就是引起crash的位置。讓我們來看看,到底是以為上面行為引起的呢?

Android NDK Crash 日志抓取及定位Android NDK Crash 日志抓取及定位

哦? 是建立了Object一起的? 納尼? 建立 Object會引起什麼crash? 這個時候讓我們回到第一章抓取的日志,其中的message有說明為(local reference table overflow (max=512)):

Android NDK Crash 日志抓取及定位Android NDK Crash 日志抓取及定位

哦,原來如此,是因為建立了過多的Object,導緻本地變量過多,溢出了。是以降注釋掉的那行代碼打開就行,用完就釋放掉。

總結

本文講述了使用Android Stuido過濾日志、NDK-Stack、arm-linux-androideabi-addr2line等三種方式,其實每種都有各自的特性,用好,用順手為重要的。