1. 程式人生 > >Android除錯之Framewrok Native除錯

Android除錯之Framewrok Native除錯

概述

我們知道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) #編譯出來的是可執行檔案