使用脚本工具快速进行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 ... >
-
程序就会在断点处停下来,现在就可以开始愉快的调试了