最近我的安卓項目中,native模塊都是在linux環境下編譯成so後再放到android studio工程中使用的,網上常見的gdb/ndk-gdb教程並不完全適用於我們項目,所以我總結了一份文檔,供大家參考使用。
1.環境準備
主機環境:ubuntu 18.04 in virtualBox
安卓平臺:android 7.0 手機
android NDK: r14b
注意 android手機要有完全的root權限,ubuntu中也需提前配置好adb環境
將手機usb透傳進虛擬機:
virtualBox菜單欄 ->設備 -> USB -> 選擇對應的手機usb端口
下文中,PHONE:#
表示手機端(android)shell的命令,PC:$
表示主機端(ubuntu)shell的命令。
2.安裝gdbserver
先確認手機cpu的類型
PHONE:# getprop ro.product.cpu.abi
我這臺手機返回 armeabi-v7a
,對應的32位gdbserver,路徑在NDK文件中:
~/android/android-ndk-r14b/prebuilt/android-arm/gdbserver/gdbserver
如果返回的是armeabi-v8a
,對應的是64位的gdbserver,路徑在:
~/android/android-ndk-r14b/prebuilt/android-arm64/gdbserver/gdbserver
將gdbserver文件PUSH進手機並修改權限
PC:$ adb remount
PC:$ adb push gdbserver /system/bin
PC:$ adb shell chmod 755 /system/bin
android 4.4以上的機器,請關閉selinux,否則gdbserver可能無法attach到應用的進程上
PHONE:# echo 0 > /sys/fs/selinux/enforce
最後可以檢查一下gdbserver的版本號來確認其有沒安裝好
PHONE:# gdbserver --version
GNU gdbserver (GDB) 7.11
3.修改要調試LIB庫的編譯參數
so lib庫需要增加一些debug的編譯參數,修改Application.mk增加:
PROJECT/jni/Application.mk
APP_OPTIM := debug
APP_CFLAG:=-O0 -ggdb3 -fno-inline -g
然後編譯出來帶符號表的so文件在:
PROJECT/obj/local/armeabi-v7a/
這裏比較簡單的辦法是直接在工程中使用上面生成的so文件,即直接覆蓋android工程中的原來文件,後面就不需要再手動指定符號表的so文件了
4.GDB使用
先在手機上查詢你應用的進程號
PHONE:# ps | grep "YOUR_PROJECT_NAME " | awk ‘{print $2}’
11856
把gdbserver attach上去,指定某端口(這裏以6000爲例)
PHONE:# gdbserver remote:6000 --attach 11856
Attached; pid = 11856
Listening on port 6000
上面沒有報錯說明attach成功了,新開一個shell窗口,將手機上的6000端口轉發到pc的6000端口
PC:$ adb forward tcp:6000 tcp:6000
再去找ndk自帶的gdb,在如下路徑
~/android/android-ndk-r14b/prebuilt/linux-x86_64/bin/gdb
ndk路徑下還有一個ndk-gdb,實質上ndk-gdb只是個py腳本,最終還是調用上面的gdb
運行上面的gdb,注意不要和ubuntu系統安裝的gdb弄混了,這裏 gdb版本應該是和上面的gdbserver對應的
PC:$ ./gdb
GNU gdb (GDB) 7.11
如果上面第3步沒有把帶符號表的so覆蓋到android工程裏面,這裏需要手動指定這些so的路徑(做了上面第3步請無視下面命令)
(gdb) set solib-search-path ~/SOURCE/PROJECT/obj/local/armeabi-v7a/
把gdb和遠程的gdbserver連接起來
(gdb) target remote :6000
此時,gdb會將手機所有的lib都加載(包括我們應用中帶符號表的so),期間你的應用可能會顯示"停止響應",按繼續等待就好了
加載完成後,終於可以用gdb進行愉悅的調試了_
~ EOF ~