欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

探究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);