Android Studio中三方so庫的源碼調(diào)試

一代态、需求背景

Android Studio 2.2+版本支持使用CMake構(gòu)建native庫,同時調(diào)試器也能對自構(gòu)建的native代碼進行源碼的調(diào)試腕侄,我們可以像調(diào)試java代碼一樣方便地調(diào)試native代碼黔漂。
我們很多的項目都依賴的so庫,有些是我們單獨的庫工程中的慈省,有些是三方提供的。如果想在主工程中調(diào)試這些庫的源碼眠菇,一種方法添加子工程或者CMake子模塊關(guān)聯(lián)源碼边败,作為自身構(gòu)建的一部分袱衷,當然需要所有的子工程都編譯通過。
搭建多工程環(huán)境和構(gòu)建子工程本身就是一個耗時又麻煩的事情笑窜,我們希望和庫工程盡量不要耦合致燥,而且調(diào)試時不需要再去構(gòu)建庫工程。

問題:我們本地有so庫對應(yīng)版本的源碼排截,也有帶符號so文件嫌蚤,如何進行源碼的調(diào)試?

二断傲、工程示例

這里我們示例一個簡單的庫工程mylib搬葬,它的c++代碼中封裝了一個求平均數(shù)的方法,然后java對外暴露了native的接口艳悔。

#include <jni.h>

extern "C"
JNIEXPORT jint JNICALL
Java_smarttime_tsia_com_mylib_MyLibNative_nativeCalAverage(JNIEnv *env, jclass type, jint a, jint b) {

    int sum = a+b;

    int avg = sum/2;

    return avg;
}

MyLibNative.java

package smarttime.tsia.com.mylib;

public class MyLibNative {

    static {
        System.loadLibrary("test-lib");
    }

    public static native int nativeCalAverage(int a, int b);
}

然后我們將它打包成一個armeabi-v7a架構(gòu)的so庫(libtest-lib.so):

我們APP主工程中,依賴這個三方庫(可以通過fileTree或maven)女仰,有一個按鈕點擊觸發(fā)調(diào)用nativeCalAverage:

public class MainActivity extends AppCompatActivity {
    ...
    void onClick(View v) {

        int ret = MyLibNative.nativeCalAverage(3,5);
    }
}

三猜年、源碼調(diào)試

要在主工程中進行源碼調(diào)試,首先要有源碼疾忍,這邊要注意要和主工程依賴的版本對應(yīng)乔外。工程依賴的三方庫都是不帶符號的,我們可以解壓APK查看libtest-lib.so一罩,stripped表示調(diào)試信息已經(jīng)去掉了

1. 獲取符號文件

符號文件中包含了行號信息杨幼,這樣調(diào)試器就知道符號地址對應(yīng)的行號,也包含源碼文件的信息聂渊,這樣在IDE中調(diào)試器就能調(diào)到對應(yīng)的文件中的某一行了差购。

在庫工程中,雖然發(fā)布的時候so去掉了調(diào)試信息汉嗽,但是構(gòu)建時會生成cmake原始的構(gòu)建產(chǎn)物欲逃,其中帶有符號信息,注意到帶符號的so要比不帶符號的要大很多

2. 調(diào)試過程和原理

1)啟動調(diào)試器

可通過Debug 'app'或者Attach Debugger to Process的方式饼暑,后者無需重啟應(yīng)用稳析,注意選擇Debug Type為native,因為我們要調(diào)試的是native代碼弓叛。

2)設(shè)置斷點

調(diào)試器連接上進程之后彰居,點擊pause program,然后我們在jni方法Java_smarttime_tsia_com_mylib_MyLibNative_nativeCalAverage設(shè)置一個斷點撰筷,source info可以查看當前堆棧的源碼和行號信息陈惰,但這時候我們還沒有符號文件,所以只能看到一個它的地址闭专。

3)添加符號文件

add-dsym可以添加指定的符號文件奴潘,如果這時候libtest-lib.so還沒有加載進來就會添加失敗旧烧,匹配不到對應(yīng)的模塊。

add-dsym的時候我們?nèi)〉檬莔ylib庫工程中cmake的構(gòu)建產(chǎn)物画髓,現(xiàn)在我們將庫工程的源碼在主工程的IDE中打開掘剪。這時我們通過IDE在文件中打斷點就能看到行號都已經(jīng)對上了。

4)觸發(fā)斷點

斷點觸發(fā)以后奈虾,source info查看到當前的行號已經(jīng)有了夺谁,源碼信息也指向我們工程中打開的源碼文件,所以IDE就跳到對應(yīng)的斷點上了肉微,然后我們就可以進行單步調(diào)試匾鸥、條件斷點、watch point等調(diào)試了碉纳。

實際調(diào)試中只要調(diào)試器連接到進程勿负,然后添加調(diào)試符號就行了,然后Android Studio中在對應(yīng)的源碼文件中直接打斷點調(diào)試即可劳曹,上述過程只是方便分析原理奴愉。

3. 源碼映射

上述的符號文件和源碼是在庫工程里,符號文件是源碼構(gòu)建生成的铁孵,所以我們添加了符號文件就能調(diào)試源碼了锭硼。實際在很多項目中庫構(gòu)建和發(fā)布都是在一臺專門用來打包的服務(wù)器(云端)上進行的,本地只有對應(yīng)版本的源碼蜕劝,為了保證一致性檀头,主工程依賴的是打包機器發(fā)布的庫,我們也用打包機器上生成的符號文件來調(diào)試岖沛。
打包機器和本地生成的符號文件唯一的不同就是構(gòu)建環(huán)境暑始,也就是源碼文件的路徑信息。我們來模擬一下烫止,假設(shè)上述在mylib工程的目錄就是打包發(fā)布的專用目錄蒋荚,而我們要調(diào)試的native代碼放在了另一個目錄里。

打包時環(huán)境:/Users/derek/Documents/AndroidProject/jniTest2/mylib/src/main/jni/test.cpp
調(diào)試源碼路徑:/Users/derek/Downloads/src/test.cpp

符號文件添加后馆蠕,斷點到j(luò)ni方法期升,雖然有行號信息,但IDE中并沒有調(diào)到對應(yīng)的文件互躬,因為這時候調(diào)試器只知道符號文件的源碼信息播赁,它沒有指向本地要調(diào)試的源碼。

執(zhí)行LLDB的setting set target.source-map命令把符號文件中的源碼信息指向本地調(diào)試的文件路徑吼渡,設(shè)置成功后容为,可以看到斷點就生效了,這時候source info也改變了。

4. Android Studio Debugger配置

以上我們都是通過執(zhí)行l(wèi)ldb命令來添加符號坎背、源碼映射的替劈,如果覺得麻煩Android Studio也提供了Debugger配置:

Symbol Directories為符號目錄,調(diào)試器會遞歸的尋找這個目錄下的文件得滤,直到匹配到需要的符號文件為止陨献;LLDB Post Attach Commands為調(diào)試器連接到進程后執(zhí)行的命令,我們可以在這里添加setting set target.source-map源碼映射的命令懂更。

如果通過Debugger配置來調(diào)試眨业,必須用Debug 'app'的方式,不能使用Attach的方式沮协,因為只有前者才會去執(zhí)行Debugger里的命令龄捡。

參考:

http://lldb.llvm.org/tutorial.html
https://developer.android.com/studio/run/rundebugconfig?hl=zh-cn#definingbefore

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市慷暂,隨后出現(xiàn)的幾起案子聘殖,更是在濱河造成了極大的恐慌,老刑警劉巖行瑞,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件就斤,死亡現(xiàn)場離奇詭異,居然都是意外死亡蘑辑,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門坠宴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來洋魂,“玉大人,你說我怎么就攤上這事喜鼓「笨常” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵庄岖,是天一觀的道長豁翎。 經(jīng)常有香客問我,道長隅忿,這世上最難降的妖魔是什么心剥? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮背桐,結(jié)果婚禮上优烧,老公的妹妹穿的比我還像新娘。我一直安慰自己链峭,他們只是感情好畦娄,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般熙卡。 火紅的嫁衣襯著肌膚如雪杖刷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天驳癌,我揣著相機與錄音滑燃,去河邊找鬼。 笑死喂柒,一個胖子當著我的面吹牛不瓶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播灾杰,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼蚊丐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了艳吠?” 一聲冷哼從身側(cè)響起麦备,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎昭娩,沒想到半個月后凛篙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡栏渺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年呛梆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片磕诊。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡填物,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出霎终,到底是詐尸還是另有隱情滞磺,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布莱褒,位于F島的核電站击困,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏广凸。R本人自食惡果不足惜阅茶,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谅海。 院中可真熱鬧目派,春花似錦、人聲如沸胁赢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谅摄,卻和暖如春徒河,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背送漠。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工顽照, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人闽寡。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓代兵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親爷狈。 傳聞我的和親對象是個殘疾皇子植影,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件涎永、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,024評論 4 62
  • 我們當今的社會是互聯(lián)網(wǎng)時代思币,在互聯(lián)網(wǎng)熱火朝天的當今,人們經(jīng)常談?wù)撊斯ぶ悄埽ˋrtificial Intellige...
    印第安南閱讀 304評論 0 1
  • 現(xiàn)在人真的會飛了 不是降落傘 是飛行翼 其實飛行翼也是降落傘的一種吧 如果真的是飛行器 是應(yīng)該有動力裝置的 哪怕是...
    土山熊閱讀 135評論 0 0