第一部分 进入调试模式
通过jre提供的jdb程序可以实现命令行调试java程序。关于jdb的命令语法可以参考 官方文档。下面我讲通过实例手把手将大家学会命令行调试
Step 1 创建项目
1. mkdir -p ~/jdwp/src/main/java/com/jdwp/test
2. cd ~/jdwp/src/main/java/com/jdwp/test
3. touch Test.java
4. 编写代码Test.java
package com.jdwp.test; /** * Created by jiangbin on 2018/6/29. */ public class Test { public static void main(String[] args) { int i = 0; int j = 1; int k = i+j; System.out.println(k); } }
Step 2 编译字节码
1. cd ~/jdwp
2. mkdir classes
3. javac -g src/main/java/com/jdwp/test/Test.java -d classes
-g参数表示生成debug信息(这个很重要不能漏)
在classes文件夹下的com/jdwp/test/目录下生成了Test.class
Step 3 运行并调试
在此阶段需要开启两个Terminal。一个用来执行java命令。一个用来执行jdb命令调试
1. java命令开启调试模式(在Terminal1中)
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000 -cp classes/ com.jdwp.test.Test
如果命令行输出以下内容表示进入调试模式成功
Listening for transport dt_socket at address: 8000
2. 执行jdb命令(在Terminal2中)
jdb -attach 8000
如果命令行输出以下内容表示成功
设置未捕获的java.lang.Throwable 设置延迟的未捕获的java.lang.Throwable 正在初始化jdb... VM 已启动: > 当前调用堆栈上没有帧 main[1]
Step 4 调试
这一步的操作都是在Terminal2中进行的
1. 设置断点
输入 stop in com.jdwp.test.Test.main(表示在Test的main方法打断点)
命令行出现如下提示,表示断点成功
正在延迟断点com.jdwp.test.Test.main。 将在加载类后设置。
2. 执行命令
1.输入next,next相当于执行一步方法 2.输入locals,会打印方法本地变量表 3. ...更多命令
何进入调试模式相信大家都会了吧。jdb除了next locals两命令。它有16个调试命令。下面我就一一讲解下
2. jdb命令全面分析
前面的内容通过实例告诉大家如何调试程序。为了过程的连续性,不产生打断,没有过多的讲解jdb的详细内容。比如打断点,前面讲解了 在方法内打断点,那如果想具体到行号,改如何设置。调试的其他命令也没有讲解。下面我将为大家做一个比较全面的讲解
1.设置断点
stop in java.lang.String.length stop in MyClass.<init> stop in MyClass.<init>(java.lang.String) //带参数的 stop at MyClass:10//在第1行中断
2.命令
connectors – 列出此 VM 中可用的连接器和传输
run [class [args]] – 开始执行应用程序的主类
threads [threadgroup] – 列出线程
thread – 设置默认线程
suspend [thread id(s)] – 挂起线程 (默认值: all)
resume [thread id(s)] – 恢复线程 (默认值: all)
where [ | all] – 转储线程的堆栈
wherei [ | all]– 转储线程的堆栈, 以及 pc 信息
up [n frames] – 上移线程的堆栈
down [n frames] – 下移线程的堆栈
kill – 终止具有给定的异常错误对象的线程
interrupt – 中断线程
print – 输出表达式的值
dump – 输出所有对象信息
eval – 对表达式求值 (与 print 相同)
set = – 向字段/变量/数组元素分配新值
locals – 输出当前堆栈帧中的所有本地变量
classes – 列出当前已知的类
class – 显示已命名类的详细资料
methods – 列出类的方法
fields – 列出类的字段
threadgroups – 列出线程组
threadgroup – 设置当前线程组
stop in .[(argument_type,…)] – 在方法中设置断点
stop at : – 在行中设置断点
clear .[(argument_type,…)] – 清除方法中的断点
clear : – 清除行中的断点
clear – 列出断点
catch [uncaught|caught|all] | – 出现指定的异常错误时中断
ignore [uncaught|caught|all] | – 对于指定的异常错误, 取消 ‘catch’
watch [access|all] . – 监视对字段的访问/修改
unwatch [access|all] . – 停止监视对字段的访问/修改
trace [go] methods [thread] – 跟踪方法进入和退出。 – 除非指定 ‘go’, 否则挂起所有线程
trace [go] method exit | exits [thread] – 跟踪当前方法的退出, 或者所有方法的退出 – 除非指定 ‘go’, 否则挂起所有线程
untrace [methods] – 停止跟踪方法进入和/或退出
step – 执行当前行
step up – 一直执行, 直到当前方法返回到其调用方
stepi – 执行当前指令
next – 步进一行 (步过调用)
cont – 从断点处继续执行
list [line number|method] – 输出源代码
use (或 sourcepath) [source file path] – 显示或更改源路径
exclude [, … | “none”] – 对于指定的类, 不报告步骤或方法事件
classpath – 从目标 VM 输出类路径信息
monitor – 每次程序停止时执行命令
monitor – 列出监视器
unmonitor