介绍gdb调试工具

Posted by Gityuan on September 9, 2017

本文介绍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

客户端操作:

adb forward tcp:1234 tcp:1234
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 查看源码
print 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 查看符号

微信公众号 Android达摩院 | 微博 weibo.com/gityuan | 博客 留言区交流