Android除錯之Framewrok Native除錯
阿新 • • 發佈:2018-12-20
概述
我們知道Android Framework層不僅僅是隻有java程式碼,還有許多c/c++程式碼,比如MediaPlayerService,CameraService等本地系統服務,都是用c和c++實現的。這個時候我們要分析問題和追蹤程式碼最好的方式就是除錯。
那我們講解一下如何使用GDB除錯CameraService connect方法,如下:
準備條件
- 有已經編譯好的安卓原始碼(debug版)
- 使用上述映象的debug裝置
1.1除錯步驟
除錯CameraService的connect方法,流程如下:
- 進入原始碼根目錄執行
# 執行shell指令碼,配置環境
$ source build/envsetup.sh
# 然後選擇自己要除錯的編譯版本
$ lunch
- 將裝置連線上伺服器,或者在伺服器上執行虛擬機器(如果是伺服器是公用遠端的呢?見下面思考1)
- 檢視要除錯的程序ID
# CameraService執行在mediaserver程序,獲得其程序id
$ adb shell ps | grep mediaserver
- 然後連結gdb除錯該程序。
$ adb root #否則gdbserver沒有足夠的許可權attach到mediaserver程序
$ gdbclient [mediaserver的程序id]
# 這個時候進入了gdb除錯模式
# 給CameraService的connect方法打斷點
# c++方法需要加上前面的名稱空間
(gdb) b android::CameraService::connect
(gdb) i b #檢視當前的斷點
#開啟攝像頭,這個時候會黑屏,因為之前打的斷點
(gdb) c #執行到斷點
(gdb) bt #檢視當前函式棧(可以看到棧頂是connect方法)
(gdb) n #單步除錯(nexti 單步指令,l 檢視當前的程式碼,p status列印status的值)
(gdb) c #繼續執行至下一個斷點(沒斷點就直接執行完成)
以上就是所有的除錯步驟。
**思考1:**如果原始碼在遠端伺服器上,這個時候應該怎麼除錯呢? 通過wifi除錯,裝置連線wifi,保證伺服器和裝置在同一個區域網內
$ adb tcpip 5555 #在裝置端執行
$ adb connect <裝置ip地址> #在服務端執行
思考2: gdbclient是什麼,做了哪些操作呢?
#(要求Android 6.0及以上,5.0在build/envsetup.sh中找gdbclient()方法即可)
$ which gdbclient
# 可以看到gdbclient指令碼的位置
然後我們檢視裡面的程式碼就可以發現,它做了如下幾個操作:
1.設定埠轉發(adb forward) 2.啟動gdbserver,並將gdbserver attach到想要除錯的程序 3.gdb 連線上gdbserver進行除錯
PS:
gdbclient [pid]
如果連線過程中報錯,也可以分析gdbclient原始碼來解決哦
思考3: CameraService為什麼執行在mediaserver程序裡面?
$ find frameworks/ -name main_mediaserver.cpp -type f
$ vi [main_mediaserver.cpp檔案的路徑]
可以看到CameraService和MediaPlayerService等服務註冊到ServiceManager中。檢視同級目錄的Android.mk中的
LOCAL_MODULE := mediaserver #所以CameraService執行在mediaserver程序 include $(BUILD_EXECUTABLE) #編譯出來的是可執行檔案