avatar


IDEA中Debug的方法和技巧

操作

操作

最常用的操作有5种,如图中的标记:

  1. Step Over:程序往下执行一行。
  2. Step Into:进入方法内,可以进入自己的方法或第三方的方法,无法进入JDK的方法。
  3. Force Step Into:强制进入方法内,包括Step Into无法进入的JDK方法。
  4. Step Out:退出方法,和Step Into(Force Step Into)配合使用。
  5. Resume Program:恢复运行程序,运行到下一个断点的地方。

如果找不到上述的一些按钮,可以通过如下方法添加:

一、找到任意一个图标,右键,选择Customize Toolbar...

Customize Toolbar...

二、在弹出的窗口,点击+,选择Add Action...

Add Action...

断点

断点有四种:

  1. 行断点
  2. 方法断点
  3. 字段断点
  4. 异常断点

行断点

行断点,是一种最常用的断点,在断点处暂停。
图标是圆形。

行断点

方法断点

方法断点,作用在方法上,通常我们会打在接口方法上,这样会在其实现类上断点。
有了这种断点,我们就无需通过上下文环境去分析,应该在哪个实现类上打断点。

方法断点

特别的,我们还可以定义,是在方法进入时生效、还是在方法退出时生效。
右键断点图标,即可进行定义。

方法断点

字段断点

字段断点,作用在字段上。在字段发生变更或者被访问时暂停。
图标:眼睛。

字段断点

在IDEA中,默认只有字段发生变更时暂停,我们可以设置其在被访问时也生效。
右键断点图标,即可进行定义。

异常断点

点击View Beakpoints...

异常断点

点击+,异常类型。

异常类型

例如,我们勾选了Java Exception Breakpointsjava.lang.NullPointerException

java.lang.NullPointerException

之后,即使我们没有打断点,程序也会在抛出空指针异常处暂停。

空指针异常

断点条件

例如,现在有一段代码如下:

1
2
3
4
int count = 0;
for (int i = 0; i < 100; i++) {
count = count + i;
}

我们想在i == 99的时候,暂停。
则我们可以右键点击断点的图标,在"Condition"处填入i == 99

断点条件

降帧

当我们从"A方法"已经进入"B方法"时,通过降帧(退帧)可以返回到调用B方法前。

通常用于当我们发现某个重要流程被我们跳过了,想再看一下,可以用这种方法先回退。

降帧

《1.基础语法》讨论"内存结构"的时候,我们说过,方法的执行和结束在JVM中对应的是栈帧的入栈和出栈。栈帧描述的就是方法对应的模型,而降帧(退帧)则对应的就是回退到上一个方法。

主动抛异常

右键,选择Throw Exception

主动抛异常-1

然后,在弹出框,定义异常。

主动抛异常-2

强制返回

强制结束当前程序运行流程,直接返回。

强制返回

执行表达式

执行表达式,用于执行一段我们编写的代码,可以用来查看数据、修改数据等。

假设存在一段如下:

1
2
3
4
5
6
int age = getAge();
if (age > 18) {
System.out.println("岁月是把杀猪刀");
} else {
System.out.println("他还只是一个孩子啊");
}

点击"执行表达式"
点击"执行表达式"

输入我们的表达式,执行。
输入我们的表达式,执行。

对于这种简单的修改数据,有一种简单的方法Set Value

多线程Debug

假设存在一段代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
private static void testSuspend() throws InterruptedException {
new Thread(() -> {
System.out.println("Thread 1 start");
System.out.println("Thread 1 end");
}).start();
new Thread(() -> {
System.out.println("Thread 2 start");
System.out.println("Thread 2 end");
}).start();
System.out.println("main thread end");
Thread.sleep(10000);
}

我们打个断点,再右键点击断点,会看到Suspend有两种模式:AllThread

  • Thread:暂停进入断点的线程,不影响其他线程执行。所有进入断点的线程依次Debug。
  • All:暂停全部线程。这时候只能Debug第一个暂停线程。

多线程断点

远程Debug

远程调试,调试部署在远程服务器上的应用。

注意:使用远程Debug的环境必须不能对外网访问,否则可能存在安全隐患。

配置本地

在本地新增"Remote JVM Debug"。

在本地

配置远程的地址,JVM的版本等。

JVM的版本

需要注意的是,我们选择不同的JVM版本,左侧的参数也不一样。这些参数我们需要拷贝下来,之后配置生产需要用。

配置远程

例如,我们的JVM是8版本的,即参数为

1
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005

我们在生产的启动命令为

1
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar spdbug-0.0.1-SNAPSHOT.jar

Debug

然后我们点击虫子的图标。
Debug

远程Debug即开始了。我们发一笔请求到远程的服务器,会发现在本机有断点了。

文章作者: Kaka Wan Yifan
文章链接: https://kakawanyifan.com/19906
版权声明: 本博客所有文章版权为文章作者所有,未经书面许可,任何机构和个人不得以任何形式转载、摘编或复制。

留言板