引入:
现在我们把目光转到JDWP层(它的全称是Java Debug Wire Protocol。从"Wire"这词就可以看出,它主要是起到"连线”的作用)。首先我们从JDWP层的数据包讲起。源码在JDK中很容易找到,它定义$JAVA_HOME/include/jdwpTransport.h 头文件中。
分析:
Part 1: 握手过程 (handshake )
握手包发生在Debugger(JDI端)和Target VM(JVMTI端)的传输层连接建立,并且在发送任何实际数据报之前完成的。它过程如下:
a. Debugger会发送14个字节的握手请求到Target VM,这个包的内容是14字节的ASCII字符串 “JDWP-Handshake”
b. Target VM会返回14个字节的握手响应到Debugger,其内容也是14字节的ASCII字符串,和刚才一样,“JDWP-Handshake"
这样的主要作用是为了确保 Debugger和Target VM之间通信正常。
Part2:发送具体调试请求和获得响应阶段:命令包(Command Packet)和响应包(Reply Packet)
从许多文档中, 我概括了JDWP层包的一些特点:
(1)包是无状态的
(2)命令包可以通过Debugger或者Target VM来发送。
对于从Debugger发送的命令包来说,它主要可以发送请求消息或者控制程序执行。
对于从Target VM发送的命令包来说,它可通知Debugger一些Target VM中的事件比如断点或者异常。
(3)响应包
响应包用于对于某命令包的响应,它总用于返回命令的成功或失败,并且可以携带命令包中包含的数据。
对于从Debugger发送的命令包,一般总会有响应包。
对于从Target VM发送的命令包,无需要响应包。
(4)JDWP平台对于数据包的发送是异步的,各个命令/响应包之间无顺序概念。命令包和对应的响应包通过ID来配对识别。
命令包的定义如下:
|
1
2
3
4
5
6
7
8
9
10
11
|
typedef
struct
{
jint len;
jint id;
jbyte flags;
jbyte cmdSet;
jbyte cmd;
jbyte *data;
} jdwpCmdPacket;
|
响应包的定义如下:
|
1
2
3
4
5
6
7
|
typedef
struct
{
jint len;
jint id;
jbyte flags;
jshort errorCode;
jbyte *data;
} jdwpReplyPacket;
|
补充说明:
(1)如果接收端接受到的命令包,其中携带的命令集或者命令是规范中未定义的,那么响应包的errorCode会被定义为NOT_IMPLEMENTED.
(2)ErrorCode定义如下:
|
1
2
3
4
5
6
7
8
9
10
|
typedef
enum
{
JDWPTRANSPORT_ERROR_NONE = 0,
JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT = 103,
JDWPTRANSPORT_ERROR_OUT_OF_MEMORY = 110,
JDWPTRANSPORT_ERROR_INTERNAL = 113,
JDWPTRANSPORT_ERROR_ILLEGAL_STATE = 201,
JDWPTRANSPORT_ERROR_IO_ERROR = 202,
JDWPTRANSPORT_ERROR_TIMEOUT = 203,
JDWPTRANSPORT_ERROR_MSG_NOT_AVAILABLE = 204
} jdwpTransportError;
|
本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/1587595,如需转载请自行联系原作者