探究JPDA架构第19期:深入理解JDI连接组件
最编程
2024-07-23 19:35:49
...
引入:
上文提到了JDI的Mirror机制,把整个目标虚拟机上的所有数据、类型、域、方法、事件、状态和资源,以及调试器发向目标虚拟机的事件请求等都映射成Mirror 对象。这里进一步讨论JDI的链接模块。
分析:
连接模块其主要目的是提供调试器(Debugger)到目标虚拟机(Target VM)之间的交互通道。
从连接的发起方来看:连接的发起方可以是调试器,也可以是目标虚拟机。
从连接的数量来看,一个调试器可以连接多个目标VM, 但是一个目标VM只可以连接一个调试器。
我们从调试器(Debugger)的角度,可以把连接分为主动连接和被动连接。
分类1:主动连接 (它表示调试器主动去连接Target VM)
又分两种情况:
a. 当Target VM还没启动时,则使用LaunchingConnector这种形式的连接器,它会启动目标VM并连接。
Step 1: 调试器调用 VirtualMachineManager 的 launchingConnectors()方法获取所有的LaunchingConnector的实例。
1
2
3
4
5
6
7
|
public
List<LaunchingConnector> launchingConnectors()
{
ArrayList list =
new
ArrayList(
2
);
list.add(
new
SocketLaunchingConnectorImpl(
this
));
list.add(
new
SocketRawLaunchingConnectorImpl(
this
));
return
list;
}
|
Step 2:根据传输方式或其他特征选择一个LaunchingConnector,调用其 launch() 方法启动并且连接目标虚拟机 。启动后,返回目标虚拟机的实例。
比如说,如果选用SocketLaunchingConnectorImpl,则它的launch()方法如下:
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
43
|
public
VirtualMachine launch(Map<String, ?
extends
Connector.Argument> connectionArgs)
throws
IOException, IllegalConnectorArgumentsException, VMStartException
{
getConnectionArguments(connectionArgs);
SocketListeningConnectorImpl listenConnector =
new
SocketListeningConnectorImpl(
virtualMachineManager());
Map args = listenConnector.defaultArguments();
((Connector.IntegerArgument)args.get(
"timeout"
)).setValue(
10000
);
String address = listenConnector.startListening(args);
String slash = System.getProperty(
"file.separator"
);
String execString =
this
.fHome + slash +
"bin"
+ slash +
this
.fLauncher;
execString = execString +
" -Xdebug -Xnoagent -Djava.compiler=NONE"
;
execString = execString +
" -Xrunjdwp:transport=dt_socket,address="
+ address +
",server=n,suspend="
+ (
this
.fSuspend ?
"y"
:
"n"
);
if
(
this
.fOptions !=
null
) {
execString = execString +
" "
+
this
.fOptions;
}
execString = execString +
" "
+
this
.fMain;
String[] cmdLine = DebugPlugin.parseArguments(execString);
Process proc = Runtime.getRuntime().exec(cmdLine);
|