調試原理:調試時在TARGET端(手機或模擬器或開發板等目標平臺)運行gdbserver,并將要調試的進程attach到gdbserver上;在HOST(例如PC機)端運行gdb,通過adb在TARGET和HOST之間做端口映射進行通訊。
Part1:主要工具:adb ?gdb/gdbserver
adb(android debug bridge)是一個多功能的安卓命令行工具,用戶可以用來連接模擬器和安卓設備;它是client-server架構,主要包括:client(PC端),server(PC端),daemon進程(模擬器或安卓設備端)三部分。
adb連接邏輯和基本概念,打開
gdb(GNU debugger)是常用于GNU OS的調試工具。gdb更多介紹請移步wiki
Part2:準備工作
1,編譯帶有符號表信息的目標文件(例如動態庫)
要使用gdb來調試,首先要編譯和加載帶有符號表信息的目標文件;需要加上幾個編譯選項:-O0 -ggdb3? -fno-inline -g,盡量多的帶有信息供調試
特別說明:
a,如果編譯生成的文件跟項目中加載的文件不同名,一定要改名或拷貝成后者的文件名
b,android項目中使用的動態庫文件需要符號表信息(理論上不需要,但是實踐證明是這樣的,疑惑中)
最好設置目標文件的輸出目錄的環境變量?KERNEL_OUTPUT
2,在項目的Manifest文件的application TAG中添加 “android:debuggable="true"”
非必須
注意:項目發布時要刪掉該項
3,拷貝gdbserver到安卓手機上(需要取得root權限;PC上安裝NDK)
gdbserver在安裝的ndk目錄下(最好設置環境變量ANDROID_NDK,并將$?ANDROID_NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin(64位機)添加到PATH下)
$adb push $ANDROID_NDK/ndk-bundle/prebuilt/android-arm/gdbserver ? /mnt/sdcard
再將其拷貝到/system/bin下,并加上執行權限
4,從TARGET上拷貝/system/bin/app_process到本機的目錄下,例如 ~/app_process
如果是64位機器,需要拷貝/system/bin/app_process32和/system/bin/app_process64
注意:要求必須是調試機器的該文件,換個手機就重新更新一下這個文件
Part3:配置步驟
Step_1: ?
(HOST)$ adb forward tcp:6000 tcp:6000 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
//HOST上所有6000端口通信數據將被重定向到TARGET的6000端口server上
Step_2:
(TARGET)$ ?ps | grep "" |?awk '{print $2}'? ? ? ?
//查詢進程號,可能打印多個進程號,注意區分主進程
(TARGET)$?su
(TARGET)# gdbserver :6000?--attach ? $process_id ? ? ? ? ? ? ? ? ? ? ? ? ? ?
//啟動gdbserver并接管調試進程。看到log例如:“Attached; pid = 31834 Listening on sockaddr socket debug-socket”
//說明attach成功,target處于等待命令狀態
Step_3:
(HOST)$?arm-linux-androideabi-gdb ?~/app_process ? -tui ? ? ? ? ?
//arm-linux-androideabi-gdb是ANDROID_NDK下
//使用 -tui 參數可以顯示當前執行的代碼,很直觀,強烈推薦!!!
(gdb)?target remote :6000?
//端口號跟在target上forward的端口號一致,如果出現連接超時,可以重復step_0和step_1
(gdb) set solib-search-path? ? $KERNEL_OUTPUT
//加載該目錄下的所有文件
(gdb) info sharedlibrary ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
//用 info sharedlibrary來查看目標庫文件的符號表是否加載成功
//看到例如 ?"0x9dd38868 ?0x9de4d340 ?Yes ? ? ? ? $ANDROID_HOME/generic/symbols/system/lib/sogouime"就是成功了 (好親切的YES呀!)
Step_4:
開始調試吧,可以各種打斷點,單步執行,打印變量了!!!
補一下強大的gdb命令吧 ? list... ? break... ? ?step... ?continue...
真得說GDB的打印功能很強大很貼心 ?能直接打印結構體變量!
-----------------------------------------------------------------------------
gdb調試原理
關于ptrace:linux函數,父進程可以用它來控制子進程,改變執行進程、查看子進程的數據等
動態庫和符號表: