使用jdwp远程debug java代码

本文转自 ieda-远程调试(java -agentlib:jdwp)

背景

当项目投产后,可能会遇到之前测试环境上没有遇到的问题,而又无法快速定位问题原因,令人十分捉急。
如果开发人员电脑可以接入生产环境,则可以采用java -agentlib:jdwp命令、idea或eclipse进行远程调试。
本文中使用IDEA进行远程调试。

#概念介绍

-agentlib 是什么

agentlib表示加载本机的代理库,输入java命令后,可以看到agentlib的介绍

1
2
3
4
5
6
7
8
-agentlib:<libname>[=<选项>]
加载本机代理库 <libname>, 例如 -agentlib:hprof
另请参阅 -agentlib:jdwp=help 和 -agentlib:hprof=help
-agentpath:<pathname>[=<选项>]
按完整路径名加载本机代理库
-javaagent:<jarpath>[=<选项>]
加载 Java 编程语言代理, 请参阅 java.lang.instrument

JDWP 是什么?

JDWP 是 Java Debug Wire Protocol 的缩写,它定义了调试器(debugger)和被调试的 Java 虚拟机(target vm)之间的通信协议。

当使用java -agentlib:jdwp启动jar时,表示也在会address对应的端口上启动一个tcp监听,等待客户端(调试端,比如idea、eclipse)连接。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

Java Debugger JDWP Agent Library
--------------------------------

(see http://java.sun.com/products/jpda for more information)

jdwp usage: java -agentlib:jdwp=[help]|[<option>=<value>, ...]

Option Name and Value Description Default
--------------------- ----------- -------
suspend=y|n wait on startup? y
transport=<name> transport spec none
address=<listen/attach address> transport spec ""
server=y|n listen for debugger? n
launch=<command line> run debugger on event none
onthrow=<exception name> debug on throw none
onuncaught=y|n debug on any uncaught? n
timeout=<timeout value> for listen/attach in milliseconds n
mutf8=y|n output modified utf-8 n
quiet=y|n control over terminal messages n

Obsolete Options
----------------
strict=y|n
stdalloc=y|n

Examples
--------
- Using sockets connect to a debugger at a specific address:
java -agentlib:jdwp=transport=dt_socket,address=localhost:8000 ...
- Using sockets listen for a debugger to attach:
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y ...

Notes
-----
- A timeout value of 0 (the default) is no timeout.

Warnings
--------
- The older -Xrunjdwp interface can still be used, but will be removed in
a future release, for example:
java -Xdebug -Xrunjdwp:[help]|[<option>=<value>, ...]

远程debug操作

操作可以分为2类
1、idea作为服务,等待客户端连接
2、其他java进程作为服务,等待idea客户端连接
本文采用方式2

服务端配置

服务端启动jar命令,增加java -agentlib:jdwp,如下:

1
2
3
4
# 需要保证-agentlib:jdwp命令在 -jar命令之前
# server=y 表示是服务端
# syspend=n 表示启动时是否阻塞等待
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar xxx.jar

客户端idea配置

使用的是idea remote jvm debug功能,如下图所示

启动调试

1、启动jar
2、在idea中启动配置好的Remote
3、在源码中打断点,就可以调试

另Arthas很强大,也可以使用Arthas进行线上调试。