[TOC]

1. 前言

我们在使用idea启动debug时可以做好多事情,看变量的值; 随处打断点; 计算变量的值等等, 这些功能全都依赖了java的调试体系JPDA(Java Platform Debugger Architecture), 而java也提供了命令行级别的调试

2. 调试使用

关键命令

  1. javac -g src/HelloJDB.java

-g 表示展示调试信息

这样就启动了程序,然后打开调试程序

  1. jdb HelloJDB.class

img

使用JDB调试Java程序 - 娄老师 - 博客园 (cnblogs.com)

由此可见,idea那么丰富的调试功能基本来源jvm

3. JPDA

JPDA 由三个规范组成:JVMTI(JVM Tool Interface)、JDWP(Java Debug Wire Protocol)、JDI(Java Debug Interface)

这三个规范的层次由低到高分别是 JVMTI、JDWP、JDI

这三个规范把调试过程分解成几个概念:调试者(debugger)、被调试者(debuggee)、以及它们中间的通信器

img

JPDA 被抽象为三层实现。其中 JVMTI 是 JVM 对外暴露的接口。JDI 是实现了 JDWP 通信协议的客户端,调试器通过它和 JVM 中被调试程序通信。

模块层次编程语言作用
JVMTI底层C获取及控制当前虚拟机状态
JDWP中介层C定义 JVMTI 和 JDI 交互的数据格式
JDI高层Java提供 Java API 来远程控制被调试虚拟机

IDEA 的 debug 怎么实现?出于这个好奇心,我越挖越深! - 知乎 (zhihu.com)

Java-JPDA 概述 - 江湖小小白 - 博客园 (cnblogs.com)

Q&A

  1. 为什么在debug中没有重排序了?

    ​ 为了保证代码的顺序性,应该是做了禁止重排序的处理(包括指令/编译/内存重排序)

    ​ 应该是在JVMTI这一层处理的,因为它包含了 虚拟机中线程、内存、堆、栈、类、方法、变量,事件、定时器处理等等诸多功能

    Java-JPDA 概述 - 江湖小小白 - 博客园 (cnblogs.com)

  2. 在debug中怎么实现动态代码的?(改了代码无需重启,甚至直接修改变量值)

    使用了动态字节码技术ASM, 使得代码的修改能直接被jvm识别并执行

    动态字节码技术还有很多,比如CGlib/Aspectj/agent等等, 动态字节码技术详解

    IDEA 的 debug 怎么实现?出于这个好奇心,我越挖越深! - 知乎 (zhihu.com)

    我们在启动被 Debug 的 JVM 时,必须添加参数 -agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:3333,而 -agentlib 选项就指定了我们要加载的 Java Agent,jdwp 是 agent 的名字,在 linux 系统中,我们可以在 jre 目录下找到 jdwp.so 库文件。

    Java 的调试体系 jdpa 组成,从高到低分别为 jdi->jdwp->jvmti,我们通过 JDI 接口发送调试指令,而 jdwp 就相当于一个通道,帮我们翻译 JDI 指令到 JVM TI,最底层的 JVM TI 最终实现对 JVM 的操作。

Java 动态字节码技术 - 枕边书 - 博客园 (cnblogs.com)