Debug 工具之 JDB
- 前言
- 夏虫不可语于冰
AOSP 调试工具 JDP 使用文档
一、概述
JDP(Java Debugger Protocol)是一种基于 JDWP(Java Debug Wire Protocol) 的调试协议,广泛应用于调试 Android Framework 和 SystemServer 进程。JDP 可通过 jdb
、Android Studio
或 IDEA
等调试工具连接至目标虚拟机,实现设置断点、单步调试、查看堆栈、变量等功能。
在 AOSP(Android Open Source Project)开发中,利用 JDP 可以定位 SystemServer 中服务的初始化问题、Binder 调用异常等系统级问题。
二、JDP/JDWP 调试前提
- 已开启
ro.debuggable=1
。 - 目标进程支持 JDWP(SystemServer 默认支持)。
- 可通过 ADB 通信。
- 主机和设备间端口转发已配置。
三、连接调试步骤(以 SystemServer 为例)
步骤 1:确保设备开启调试模式
1 | adb root |
确认 ro.debuggable
属性是否为 1
:
1 | adb shell getprop ro.debuggable |
若不是 1
,需刷入 userdebug 或 eng 版系统。
步骤 2:查看支持 JDWP 的进程
1 | adb jdwp |
会输出类似:
1 | 5 |
记录目标进程的 PID, 可以通过 ps -A | grep -insH "systemui"
查询对应的 PID。
步骤 3:设置端口转发
将本地端口(如 8800)映射到目标进程的 JDWP 接口:
1 | adb forward tcp:8800 jdwp:<PID> |
示例:
1 | adb forward tcp:8800 jdwp:1632 |
步骤 4:使用调试器连接
方法一:使用 jdb 工具(推荐)
1 | jdb -attach localhost:8800 |
若连接成功,控制台将进入 JDB 调试界面。
方法二:使用 Android Studio / IDEA
打开调试配置 > 添加 Remote JVM Debug。
设置:
- Host:
localhost
- Port:
8800
- Transport:
Socket
- Host:
点击连接。
四、常用 JDB 命令表
命令 | 说明 |
---|---|
help |
显示帮助命令列表 |
classes |
显示已加载的类 |
methods <类名> |
查看类中方法 |
stop in <类名>.<方法名> |
在指定方法设置断点 |
clear <类名>:<行号> |
清除指定行断点 |
run |
启动程序(首次连接不用) |
cont |
继续执行 |
next |
单步执行(不进入方法) |
step |
单步执行(进入方法) |
print <变量> |
打印变量值 |
where |
打印当前线程堆栈 |
thread |
显示线程信息 |
threads |
显示所有线程 |
exit |
退出调试器 |
- 使用案例(Android P 分析 LayoutInflater.inflate )
1 | 查询可调试进程 |
五、调试技巧与注意事项
1. SystemServer 多线程注意
- SystemServer 内部启动多个服务线程,调试时应先用
threads
找到目标线程,使用thread <id>
切换再打断点。
2. 设置断点位置建议
- 推荐在
.java
文件中查找行号或方法名,然后在 JDB 中使用stop in
或stop at
设置断点。
3. 连接失败常见原因
问题 | 原因 | 解决方法 |
---|---|---|
Unable to attach |
PID 不存在 / JDWP 不支持 | 确认使用的 PID 正确并支持 JDWP |
无法进入 JDB | 被防火墙阻断 / 未转发端口 | 关闭防火墙、确认 adb forward 正确 |
JDB 显示乱码 | JDK 编码问题 | 设置 JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 |
六、附录:如何让自定义服务支持 JDWP
若要调试自定义 native 服务或 Java 服务,可在启动代码中添加:
1 | Debug.waitForDebugger(); // 启动时等待调试器连接 |
或
1 | if (android.os.Debug.isDebuggerConnected()) { |
并确保 ro.debuggable=1
和服务是以 app_process 启动的 Java 进程。
如需进一步集成 JDP 调试进 IDE,也可将 out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
添加为依赖,获得完整调试符号。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 落雪のBlog!