Android FrameWork學(xué)習(xí)(二)Android系統(tǒng)源碼調(diào)試

通過上一篇 Android FrameWork學(xué)習(xí)(一)Android 7.0系統(tǒng)源碼下載\編譯 我們了解了如何進行系統(tǒng)源碼的下載和編譯工作。

為了更進一步地學(xué)習(xí)跟研究 Android 系統(tǒng)源碼撕捍,今天我們來講講如何進行 Android 系統(tǒng)源碼的調(diào)試著瓶,只有學(xué)會了如何進行系統(tǒng)源碼的調(diào)試,才能幫助我們更高效地閱讀跟理解源碼类垫。

我們知道,Android Framework 的代碼主要由Java、C\C++等代碼組成仔掸,因此,對于系統(tǒng)源碼的調(diào)試医清,我們這里將其分為了兩部分

  • Java 相關(guān)代碼的調(diào)試
  • C\C++ Native 相關(guān)代碼的調(diào)試

一起暮、Java 相關(guān)代碼的調(diào)試

對于 Java 相關(guān)代碼的調(diào)試,這里我們主要使用 Android Studio 開發(fā)工具來進行会烙。

導(dǎo)入源碼到 Android Studio

要在 Android Studio 中調(diào)試源碼负懦,那第一步自然是導(dǎo)入系統(tǒng)源碼到 Android Studio 中了。

1. 編譯 idegen

對于 Android 源碼的導(dǎo)入柏腻, Google 官方給我們提供了一個很方便的工具 idegen

它位于我們所下載的系統(tǒng)源碼路徑中:

developement/tools/idegen

引用 README 的一句話

IDEGen automatically generates Android IDE configurations for IntelliJ IDEA
and Eclipse.

idegen 工具會自動生成針對 Android 開發(fā)工具(Android Studio和Eclipse)的配置文件纸厉。

既然如此,那我們就來使用 idegen 工具生成導(dǎo)入源碼所需的配置文件五嫂。

首先打開命令行工具颗品,cd 進入到源碼路徑下,

執(zhí)行如下指令:

#初始化命令工具
soruce build/envsetup.sh 
#編譯 idegen 模塊沃缘,生成idegen.jar
mmm development/tools/idegen/
#生成針對 Android 開發(fā)工具的配置文件 
sudo ./development/tools/idegen/idegen.sh

在執(zhí)行完上述指令后躯枢,會在源碼路徑下生成下面三個文件

Paste_Image.png

android.ipr:工程相關(guān)的設(shè)置,比如編譯器配置槐臀、入口锄蹂,相關(guān)的libraries等。

android.iml:描述了modules水慨,比如modules的路徑,依賴關(guān)系等得糜。

android.iws:包含了一些個人工作區(qū)的設(shè)置敬扛。

2. 導(dǎo)入源碼

接下來我們可以開始導(dǎo)入源碼了.

如果你是第一次導(dǎo)入源碼, Android Studio 可能需要占用大量的內(nèi)存掀亩,我們需要設(shè)置下我們的 VM 選項舔哪。

Linux 設(shè)備的話在 Android Studio 的 bin/studio64.vmoptions 文件中添加-Xms748m -Xmx748m

如果你使用的是 Mac 槽棍,那么在 AS 目錄的 Contents/Info.plist 目錄中進行添加捉蚤。

由于 Android 的系統(tǒng)源碼非常龐大,一次性導(dǎo)入 Android Studio 的話需要加載非常長的時間

因此炼七,在正式開始導(dǎo)入前缆巧,我們可以打開 android.iml 文件根據(jù)自己需要調(diào)整要加載的源碼。

Paste_Image.png

這里 <excludeFolder> 表示不需要加載的目錄豌拙,我們根據(jù)自己的需要使用 <excludeFolder> 標(biāo)簽添加對應(yīng)的目錄地址即可陕悬。

接著,選擇 File -> open 選中 android.ipr 文件按傅,打開

Paste_Image.png

這時 Android Studio 就會開始加載源碼了

在沒有添加修改 <excludeFolder> 的情況下捉超,這個加載的時間會比較長,經(jīng)過一段時間的等待后唯绍,代碼就加載完畢了拼岳,如圖:

Paste_Image.png

這里紅色的目錄代表被 exclude 排除了,代碼加載 scan index 的時候會過濾掉該目錄况芒。

在加載完源碼后惜纸,我們也可以在 Project Structure 中的 Module 選項中右鍵 exclude 來排除不需要加載的源碼目錄,如圖:

Paste_Image.png
Paste_Image.png

3. 配置代碼依賴绝骚,確保代碼跳轉(zhuǎn)正確

為了閱讀和調(diào)試代碼的時候能夠保證代碼跳轉(zhuǎn)正確耐版,我們需要配置下相關(guān)依賴。

首先是 AOSP 源碼的跳轉(zhuǎn)压汪,我們通過 File -> Project Structure 打開 Module粪牲,然后選中 Dependencies, 保留 JDK 跟 Module Source 項止剖,并添加源碼的 external 和 frameworks 依賴虑瀑,如圖:

Paste_Image.png

然后是 SDK 的設(shè)置,確保關(guān)聯(lián)對應(yīng)版本的 SDK 于系統(tǒng)版本一直

Paste_Image.png

開始調(diào)試源碼

調(diào)試前要設(shè)置 Project 的 SDK 滴须, File -> Project 下打開 Project Structure舌狗,選中 Project 設(shè)置對應(yīng)版本的 SDK,于系統(tǒng)版本一致:

Paste_Image.png

確保 Android Studio 允許 ADB 調(diào)試

Paste_Image.png

接著我們參照上一篇文章中講的方法打開 Android 模擬器

此時點擊 Android Studio 工具欄的 attach debugger to Android process 按鈕扔水,會打開 Choose Process 窗口痛侍,我們根據(jù)自己需要調(diào)試的代碼選擇對應(yīng)的進程:

Paste_Image.png

這里假設(shè)我們要調(diào)試 Android 自帶瀏覽器的源碼,如圖,我們在它的入口文件 WebViewBrowserActivity 中的 loadUrlFromUrlBar 方法中打上斷點主届。

Paste_Image.png

點擊 WebViewBrowser 打開 app


Paste_Image.png

打開之后赵哲,點擊 attach to Android process 按鈕打開 choose Process,可以看到 webViewBrowser 運行的進程君丁,選中枫夺,ok

Paste_Image.png

然后我們在 app 的 url 輸入欄輸入 網(wǎng)址進行跳轉(zhuǎn)

Paste_Image.png
Paste_Image.png

如圖所示我們可以看到,代碼成功進入了斷點绘闷,然后我們就可以隨心所欲地調(diào)試我們想要的調(diào)試的 Java 代碼了橡庞。


二、Native C\C++ 相關(guān)代碼調(diào)試

對于 Framework Native 代碼印蔗,我們這里使用 GDB 工具來進行調(diào)試扒最。

什么是 GDB 呢?

它是一款 GNU 項目調(diào)試工具华嘹,它的功能非常強大吧趣,可以用來調(diào)試 C 、C++耙厚、Object-C强挫、Pascal 等語言編寫的項目。

對于使用習(xí)慣了可視化 IDE 的同學(xué)們來說薛躬,它最大的缺點可能就是它不支持圖形化了

但是 GDB 提供的指令非常靈活纠拔,通過指令我們

  • 可以隨心所欲地啟動程序,
  • 可以根據(jù)自己的需要設(shè)置斷點泛豪,
  • 可以查看斷點處的變量,代碼信息
  • 可以查看程序運行的調(diào)用棧

一旦你熟悉了它侦鹏,你便可以玩得飛起诡曙!

一般情況下,使用 gdb 來調(diào)試 Android 源碼需要在 Android 設(shè)備上安裝 gbdserver attach 關(guān)聯(lián)我們需要調(diào)試的進程略水,再使用 gdb 指令去連接 gdbserver 進行調(diào)試

不過官方給我們提供了 gdbclient 工具价卤,可以讓我們方便地進行 gdb 調(diào)試。

開始 GDB 調(diào)試

這里我們就基于 gdbclient 來進行實際的 gdb 調(diào)試演示:

跟上面 Java 調(diào)試一樣渊涝,我們這里還是以系統(tǒng)自帶的瀏覽器為例慎璧。

1. 點擊啟動圖標(biāo)打開瀏覽器 app:

Paste_Image.png

2. 打開一個命令行終端,cd 進入到系統(tǒng)源碼目錄(我的源碼路徑為 aosp)跨释,初始化命令工具:

#進入源碼路徑
cd aosp
#初始化命令工具
source build/envsetup.sh
#選擇編譯的源碼的版本胸私,參考上一篇文章
lunch
初始化命令工具
Paste_Image.png

3. 通過 adb 指令來查找要調(diào)試進程的 PID

# 通過 shell ps 指令查找相關(guān)進程,grep 搜索過濾 webview 進程
adb shell ps -A | grep webview
Paste_Image.png

如圖鳖谈,2157 為系統(tǒng)自帶瀏覽器 app 所在進程的 PID

4. 使用 gdbclient <app pid> 命令工具啟用 gdb 調(diào)試 PID 對應(yīng)進程

# gdbclient <app pid> 可以啟用 gdb 調(diào)試對應(yīng) PID 進程
gdbclient 2157
Paste_Image.png

等待進入 gdb 調(diào)試命令界面

Paste_Image.png

5. 使用 GDB b 命令打斷點

在 gdb 指令中岁疼,我們使用b <代碼文件>:行號 來設(shè)置斷點.

這里我們選擇 frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp 代碼文件的 drawFrame 方法打上斷點,位于文件 71 行:

Paste_Image.png

該方法主要用于繪制幀缆娃,當(dāng)瀏覽器 app 的界面發(fā)生變化時會觸發(fā)該方法捷绒。

我們輸入設(shè)置斷點命令:

b frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp:71
Paste_Image.png

輸入指令后顯示
Breakpoint 2 at 0x7f69e9892c11: file frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp, line 71.
說明我們的斷點設(shè)置成功了瑰排。

6. 在命令行輸入c 開始監(jiān)聽

Paste_Image.png

c 即 continue,此時界面上出現(xiàn) Continuing 說明開始監(jiān)聽進程了

我們點開模擬器暖侨,隨意操作椭住,觸發(fā)界面變化時,便會進入繪制幀的代碼斷點了:

Paste_Image.png

如圖字逗,顯示進入斷點京郑,這樣代表我們的代碼調(diào)試成功了。


這里我們只是演示了一個大概流程扳肛,

gdb 代碼的調(diào)試需要你對源碼有一定的熟悉傻挂,知道哪個進程會調(diào)用哪個文件方法。

同時挖息,我們還需要熟悉 gdb 的各種命令金拒,這里給大家推薦一篇不錯的入門文章,可以快速入門:

GDB十分鐘教程

這里補充一點套腹,如果你希望在某個進程啟動時就監(jiān)聽绪抛,可以使用下面的指令關(guān)聯(lián)目錄,得到 pid电禀,再通過 gdbclient 來進行調(diào)試

adb shell gdbserver :5039 /system/bin/my_test_app
Process my_test_app created; pid = 3460
Listening on port 5039
gdbclient <app pid>

如果你希望通過 Android Studio 來調(diào)試 Framework 的 C\C++ 代碼的話幢码,也可以參考下面的兩篇文章,不過個人覺得這種方法有一定的局限性尖飞。

如何調(diào)試Android Native Framework

用Android Studio調(diào)試Framework層代碼


結(jié)語

正如文章開頭所說症副,只有學(xué)會了如何調(diào)試 Framework 源碼,才能幫助我們更好地學(xué)習(xí) Android Framework政基,希望這篇文章能給大家一些幫助贞铣,如果有更好地調(diào)試方法,歡迎大家給我留言咯沮明!

最后編輯于
?著作權(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é)果婚禮上橡类,老公的妹妹穿的比我還像新娘。我一直安慰自己芽唇,他們只是感情好顾画,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著匆笤,像睡著了一般研侣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上炮捧,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天庶诡,我揣著相機與錄音,去河邊找鬼咆课。 笑死末誓,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的书蚪。 我是一名探鬼主播喇澡,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼善炫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起库继,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤箩艺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后宪萄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體艺谆,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年拜英,在試婚紗的時候發(fā)現(xiàn)自己被綠了静汤。 大學(xué)時的朋友給我發(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
  • 正文 我出身青樓闯割,卻偏偏與公主長得像彻消,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子宙拉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

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