跳至主要內容

远程调试

荒流2023年2月13日大约 4 分钟约 1144 字

远程调试与 JPDA

所谓的远程调试就是服务端程序运行在一台远程服务器上,我们可以在本地的代码(前提是本地的代码必须和远程服务器运行的代码一致)中设置断点,每当有请求打到远程服务器时能够同时在本地感知远程服务端的内部状态。

JPDA(Java Platform Debugger Architecture),即 Java 平台调试体系,具体结构图如下图所示:

JPDA 组成
JPDA 组成

其中实现调试功能的主要协议是JDWP协议。在 Java SE 5 以前版本,JVM 端的实现接口是 JVMPI(Java Virtual Machine Profiler Interface),而在Java SE 5及以后版本,使用 JVMTI(Java Virtual Machine Tool Interface) 来替代 JVMPI

如何开放远程调试的入口

由于现在使用的大多数都是Java SE 5之后的版本,则之前的就忽略了。

日常开发中最常见的开启远程调试的命令如下:

java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=10086 -jar xxx.jar

前面的java -agentlib:jdwp=是基础命令,后面的跟着的一串命令则是可选的参数,具体意思为:

命令示例

下面列举几个常用的参考命令,这样更加方便理解。

  1. Socket 方式监听 8000 端口,程序启动阻塞(suspend 的默认值为 y)直到被连接,命令如下:

    -agentlib:jdwp=transport=dt_socket,server=y,address=8000
  2. Socket 方式监听 8000 端口,当程序启动后 5 秒无调试者连接的话终止,程序启动阻塞(suspend 的默认值为 y)直到被连接:

    -agentlib:jdwp=transport=dt_socket,server=y,address=localhost:8000,timeout=5000
  3. 选择可用的共享内存连接地址并使用 stdout 打印,程序启动不阻塞:

    -agentlib:jdwp=transport=dt_shmem,server=y,suspend=n
  4. socket 方式连接到 myhost:8000上的调试程序,在连接成功前启动阻塞:

    -agentlib:jdwp=transport=dt_socket,address=myhost:8000
  5. Socket 方式监听 8000 端口,程序启动阻塞(suspend 的默认值为 y)直到被连接。当抛出 IOException 时中断调试,转而执行 usr/local/bin/debugstub程序:

    -agentlib:jdwp=transport=dt_socket,server=y,address=8000,onthrow=java.io.IOException,launch=/usr/local/bin/debugstub

IDEA 如何开启远程调试?

服务器上

首先的将打包后的Spring Boot项目在服务器上运行,执行如下命令(各种参数根据实际情况自己配置):

java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9193 -jar debug-demo.jar

项目启动成功后,进行本地配置。

本地

这里是一个创建好的示例:

image-20230213160148172