使用腳本工具快速進行Android Native調試。
安裝android_gdbserver_attach腳本
使用GDB遠程調試指定Android進程的時候,經常要查詢pid,然後再attach。爲了簡化步驟,就寫了個腳本。
file name: android_gdbserver_attach
#!/usr/bin/env bash
gdbServerPid=`adb shell ps | grep gdbserver | awk '{print $2}'`
if [[ "" != ${gdbServerPid} ]]; then
adb shell su -c "kill ${gdbServerPid}"
fi
adb forward tcp:1234 tcp:1234
if [[ `adb shell whoami` == 'root' ]]; then
is_root=true
fi
if [[ -n $1 ]]; then
OLDIFS=$IFS
IFS='
'
grepPsResult=(`adb shell ps | grep $1 | awk '{print $1"\t"$2"\t"$9}'`)
IFS=$OLDIFS
NUMPIDS=${#grepPsResult[@]}
declare -a appPid
for (( x=0; x < $NUMPIDS; x++ )); do
appPid[x]=`echo ${grepPsResult[x]} | awk '{print $2}'`
done
selectedPid=0
if [[ 0 -eq "$NUMPIDS" ]]; then
echo "No this process name - nothing to do."
exit 0;
elif [[ 1 -eq "$NUMPIDS" ]]; then
# Just one process
selectedPid=${appPid[0]}
else
# Select one process
echo "Multiple processes detected, please select one"
for (( x=0; x < $NUMPIDS; x++ )); do
echo -e "$[x+1]: ${grepPsResult[x]}"
done
echo -n "> "
read USER_CHOICE
# Validate user entered a number
if [[ $USER_CHOICE =~ ^[0-9]+$ ]]; then
echo "Selected Process : ${grepPsResult[$USER_CHOICE-1]}"
selectedPid=${appPid[$USER_CHOICE-1]}
else
echo "You must enter a number"
exit 0;
fi
fi
adb forward tcp:12345 jdwp:${selectedPid}
if [[ $is_root == true ]]; then
adb shell gdbserver :1234 --attach ${selectedPid}
else
adb shell su -c "gdbserver :1234 --attach ${selectedPid} "
fi
else
echo "Please input the name of the process to be debugged (app's process name is the package name)。Example: $0 <process name>"
fi
GDB調試正在運行的App進程
- 使用腳本attach到指定的進程
腳本後面輸入進程名,如果發現多個匹配,就會出現選擇列表,輸入數字選擇即可$ android_gdbserver_attach gms Multiple processes detected, please select one 1: u0_a40 1584 com.google.android.gms.persistent 2: u0_a40 2039 com.google.android.gms 3: u0_a40 3244 com.google.android.gms.unstable 4: u0_a40 25548 com.google.android.gms.ui > 2 Selected Process : u0_a40 2039 com.google.android.gms Attached; pid = 2039 Listening on port 1234
- 使用gdb或者clion remote gdb 連接本地端口
1234
即可
GDB在App啓動階段進行調試
-
以等待調試的方式啓動App
adb shell am force-stop <包名> && adb shell am start -n
“<包名>/<啓動的Activity名>” -a android.intent.action.MAIN -c
android.intent.category.LAUNCHER -D例如
$ adb shell am force-stop com.kevin.jni.jniworld && adb shell am start -n "com.kevin.jni.jniworld/com.kevin.jni.jniworld.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -D
出現如下圖對話框
-
使用android_gdbserver_attach腳本attach到改進程
$ android_gdbserver_attach com.kevin.jni.jniworld Attached; pid = 7578 Listening on port 1234
-
使用gdb或者CLion remote gdb 連接本地端口
1234
即可
這裏以CLion GDB Remote 配置截圖
連接成功如下圖所示
-
通過jdb attach進程
爲了讓App繼續運行,結束Waiting。需要通過jdb attach 該進程。jdwp端口轉發已經在腳本中執行了(第50行)。所以這裏直接attach即可$ jdb -attach localhost:12345 Set uncaught java.lang.Throwable Set deferred uncaught java.lang.Throwable Initializing jdb ... >
-
程序就會在斷點處停下來,現在就可以開始愉快的調試了