Android普通app在native層快速打印調(diào)用棧
經(jīng)常需要判斷某函數(shù)是否執(zhí)行,何時執(zhí)行。不知道為什么工作電腦的AndroidStudio不能附加native層調(diào)試器,如圖1所示點擊OK沒有任何反應(yīng),那最快的調(diào)試方法就只能是加日志了。

在kotlin打印調(diào)用棧只需要一行:
但在native層有點麻煩了,查過了一些資料,簡中博客大部分出自這一篇:
里面寫了系統(tǒng)級別的app如何打印native層調(diào)用棧,通常是使用libutilscallstack,但是ndk提供的頭文件并沒有CallStack.h,如圖2、3、4所示。



libutilscallstack.so在普通app實際是加載了的,如圖5:

有沒有可能使用使用dlopen+dlsym調(diào)用呢?dlopen傳入libutilscallstack.so之后,logcat輸出:
普通app,dlopen支持的系統(tǒng)的so是有限制的?;蛟S有辦法可以繞過這個限制,參考鏈接:
這個鏈接給的傳入空的方法我這里MIUI14測試無效,至于其他辦法,這不是自己的項目,不想引入太多只是為了調(diào)試用的代碼,要不然提交代碼的時候還要刪掉。

很多JVM教程上來就會演示一個叫“jstack”的工具,可以打印出JVM所有線程正在執(zhí)行的代碼。Android沒有jstack,但可以發(fā)送-3信號實現(xiàn)同樣的目的,可以直接在/data/anr/生成trace_xxx文件,內(nèi)容和觸發(fā)ANR時生成的日志一樣的。
但對于某些不帶腦子亂改Android又剝奪解鎖BL權(quán)力的獨裁廠商,我們只能發(fā)送STOP信號強(qiáng)制使進(jìn)程暫停然后觸發(fā)ANR,因為這些愚蠢的UI系統(tǒng)使用adb bugreport沒有把把/data/anr/trace_xx一起導(dǎo)出。

回到標(biāo)題,Android普通app如何在native層快速打印調(diào)用棧,只需要兩行代碼:
為什么sleep?因為kill并不是阻塞的,可能系統(tǒng)處理完-3信號的時候,代碼早就執(zhí)行到其他地方了。而這里的sleep實際上很快就會被打斷,至于為什么被打斷,我現(xiàn)在還不好說..。
