本文介紹Native異常的調(diào)試工具gdb的環(huán)境準(zhǔn)備與常見(jiàn)命令
1. 找到gdbserver
當(dāng)有Android系統(tǒng)源碼蝶念,可在/prebuilts目錄下查找,一般位于如下:
工具 | 所在源碼路徑 |
---|---|
32位gdb服務(wù)端 | prebuilts/misc/android-arm/gdbserver/gdbserver |
64位gdb服務(wù)端 | prebuilts/misc/android-arm64/gdbserver64/gdbserver64 |
32位gdb客戶端 | prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-gdb |
64位gdb客戶端 | prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-gdb |
symbols | /out/target/product/[name]/symbols |
gdbserver64和gdbserver選擇哪一個(gè)芋绸,取決于當(dāng)前手機(jī)是32位還是64位媒殉,要判定這個(gè)方法很有很多,比如
adb shell getprop ro.product.cpu.abi
2. 環(huán)境準(zhǔn)備
adb root
adb disable-verity
adb reboot
adb root
adb remout
adb push prebuilts/misc/android-arm64/gdbserver64/gdbserver64 /system/bin
adb shell setenforce 0
這里有幾點(diǎn)需要注意:
- 如果disable-verity命令不可執(zhí)行摔敛,需要選擇源碼環(huán)境下的adb命令
- 如果過(guò)程遇到selinux權(quán)限問(wèn)題廷蓉,記得關(guān)閉
3. 啟動(dòng)gdbserver服務(wù)
服務(wù)端操作:(手機(jī))
adb shell
gdbserver64 :1234 --attach 1536 //1536代表system_server進(jìn)程的pid
客戶端操作:(PC電腦)
adb forward tcp:1234 tcp:1234
//進(jìn)入gdb狀態(tài)
aarch64-linux-android-gdb
//提前配置好環(huán)境變量
target remote:1234
// 加載被調(diào)試的可執(zhí)行程序
file xxx/out/target/product/[name]/symbols/system/bin/app_process64
// 設(shè)置符號(hào)路徑
set sysroot [xxx/symbols]
//設(shè)置源碼路徑
set dir xxx
開(kāi)始調(diào)試:
b frameworks/base/core/jni/android_util_Process.cpp:1035 if sig == 19
c
4. 常見(jiàn)gdb調(diào)試命令
命令名 | 命令縮寫(xiě) | 命令說(shuō)明 |
---|---|---|
backtrace | bt | 查看函數(shù)調(diào)用堆棧 |
frame | f | 查看棧幀 |
list | l | 查看源碼 |
p | 打印內(nèi)部變量值 | |
info | i | 查看程序狀態(tài) |
display | disp | 跟蹤某變量,每次停下來(lái)則顯示值 |
run | r | 開(kāi)始運(yùn)行程序 |
continue | c | 繼續(xù)程序運(yùn)行,直到下一個(gè)斷點(diǎn) |
break | b | 設(shè)置斷點(diǎn) |
start | s | 開(kāi)始執(zhí)行程序 |
step | s | 執(zhí)行下一條語(yǔ)句马昙,若該語(yǔ)句為函數(shù)調(diào)用,則進(jìn)入函數(shù)內(nèi)的第一條語(yǔ)句 |
next | n | 執(zhí)行下一條語(yǔ)句桃犬,不會(huì)進(jìn)入函數(shù)內(nèi)部執(zhí)行 |
watch | 監(jiān)視變量值的變化 | |
file | 裝入需要調(diào)試的程序 | |
set var name=v | 設(shè)置變量的值 | |
kill | k | 殺掉正在調(diào)試的程序 |
quit | q | 退出GDB環(huán)境 |
以下列舉部分常見(jiàn)的調(diào)試命令:
命令 | 含義 |
---|---|
bt | 打印當(dāng)前線程調(diào)用棧 |
bt 10 | 打印tid=10的線程調(diào)用棧 |
thread apply all bt | 打印所有線程的調(diào)用棧 |
f 5 | 切換到調(diào)用棧的第5層 |
t 10 | 切換到tid=10的線程 |
disassemble | 查看匯編代碼 |
info reg | 查看當(dāng)前的寄存器值 |
info threads | 查看當(dāng)前進(jìn)程的所有線程 |
x /32wx 0x7198eb48 | 查看內(nèi)存 |
p *(Method*) 0x6d682328 |
查看符號(hào) |