本文介绍Native异常的调试工具gdb的环境准备与常见命令
1. 找到gdbserver
当有Android系统源码,可在/prebuilts目录下查找,一般位于如下:
工具 | 所在源码路径 |
---|---|
32位gdb服务端 | prebuilts/misc/android-arm/gdbserver/gdbserver |
64位gdb服务端 | 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选择哪一个,取决于当前手机是32位还是64位,要判定这个方法很有很多,比如
adb shell getprop ro.product.cpu.abi
2. 环境准备
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
这里有几点需要注意:
- 如果disable-verity命令不可执行,需要选择源码环境下的adb命令
- 如果过程遇到selinux权限问题,记得关闭
3. 启动gdbserver服务
服务端操作:(手机)
adb shell
gdbserver64 :1234 --attach 1536 //1536代表system_server进程的pid
客户端操作:(PC电脑)
adb forward tcp:1234 tcp:1234
//进入gdb状态
aarch64-linux-android-gdb
//提前配置好环境变量
target remote:1234
// 加载被调试的可执行程序
file xxx/out/target/product/[name]/symbols/system/bin/app_process64
// 设置符号路径
set sysroot [xxx/symbols]
//设置源码路径
set dir xxx
开始调试:
b frameworks/base/core/jni/android_util_Process.cpp:1035 if sig == 19
c
4. 常见gdb调试命令
命令名 | 命令缩写 | 命令说明 |
---|---|---|
backtrace | bt | 查看函数调用堆栈 |
frame | f | 查看栈帧 |
list | l | 查看源码 |
p | 打印内部变量值 | |
info | i | 查看程序状态 |
display | disp | 跟踪某变量,每次停下来则显示值 |
run | r | 开始运行程序 |
continue | c | 继续程序运行,直到下一个断点 |
break | b | 设置断点 |
start | s | 开始执行程序 |
step | s | 执行下一条语句,若该语句为函数调用,则进入函数内的第一条语句 |
next | n | 执行下一条语句,不会进入函数内部执行 |
watch | 监视变量值的变化 | |
file | 装入需要调试的程序 | |
set var name=v | 设置变量的值 | |
kill | k | 杀掉正在调试的程序 |
quit | q | 退出GDB环境 |
以下列举部分常见的调试命令:
命令 | 含义 |
---|---|
bt | 打印当前线程调用栈 |
bt 10 | 打印tid=10的线程调用栈 |
thread apply all bt | 打印所有线程的调用栈 |
f 5 | 切换到调用栈的第5层 |
t 10 | 切换到tid=10的线程 |
disassemble | 查看汇编代码 |
info reg | 查看当前的寄存器值 |
info threads | 查看当前进程的所有线程 |
x /32wx 0x7198eb48 | 查看内存 |
p *(Method*) 0x6d682328 |
查看符号 |