Introduced:
The mirror mechanism of JDI is mentioned above, which maps all the data, types, domains, methods, events, States, and resources of the entire target virtual machine, as well as the event requests sent by the debugger to the target virtual machine, to mirror objects. The link module of JDI is discussed further here.
Analysis:
The main purpose of the connection module is to provide an interactive channel between the debugger (Debugger) and the target VM.
From the initiator of the connection: the initiator of the connection can be a debugger, or it can be a target virtual machine.
From the number of connections, a debugger can connect to multiple target VMS, but a target VM can only connect to one debugger.
From the point of view of the debugger (Debugger), we can divide the connection into active and passive connections.
Category 1: Active connection (which indicates that the debugger actively connects to the target VM)
There are two kinds of situations:
A. When the target VM is not started, a connector of the form Launchingconnector is used, which starts the target VM and connects.
Step 1: The debugger calls Virtualmachinemanager's Launchingconnectors () method to get all instances of the launchingconnector.
Public list<launchingconnector> launchingconnectors () {ArrayList List = new ArrayList (2); List.add (New Socketlaunchingconnectorimpl (this)); List.add (New Socketrawlaunchingconnectorimpl (this)); return list; }
Step 2: Select a launchingconnector based on transmission or other characteristics, call its launch () method to start and connect to the target virtual machine. When started, returns an instance of the target virtual machine.
For example, if you choose Socketlaunchingconnectorimpl, then its launch () method is as follows:
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 + " &NBSP;-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); try { virtualMachine = (Virtualmachineimpl) LisTenconnector.accept (args); } catch (InterruptedIOException localinterruptedioexception) { Virtualmachineimpl virtualmachine; proc.destroy (); string message = nls.bind (Connectmessages.socketlaunchingconnectorimpl_vm_did _not_connect_within_given_time___0__ms_1, new string [] { ((connector.integerargument) args .get ("timeout")). Value () }); throw new vmstartexception (Message, proc); } Virtualmachineimpl virtualmachine; virtualmachine.setlaunchedprocess (proc); return virtualmachine; }
B. When the target VM is started, a connector of the form Attachingconnector is used, which is attached to the target virtual machine.
The premise is that the Target VM must start with the-agentlib:jdwp=transport=xxx,server=y parameter in the following manner and generate a listening address based on the transport mode.
STEP1: The debugger starts, calling Virtualmachinemanager's Attachingconnectors () method to get all instances of the attachingconnector.
Public list<attachingconnector> attachingconnectors () {ArrayList List = new ArrayList (1); List.add (New Socketattachingconnectorimpl (this)); return list;
Step 2: Select a attachingconnector based on the transport used by the target virtual machine, and call its attach () method to attach to the target virtual machine. When the connection is complete, returns an instance of the target virtual machine.
public virtualmachine attach (map<string, ? extends connector.argument> connectionargs) throws ioexception, illegalconnectorargumentsexception { getconnectionarguments (Connectionargs); connection connection = null; try { connection = ((Sockettransportimpl) this.ftransport). Attach (this.fhostname, &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;THIS.FPORT,&NBSP;THIS.FTIMEOUT,&NBSP;0L); } catch (illegalargumentexception e) { List args = New arraylist (); args.add ("hostname"); args.add ("Port"); throw new Illegalconnectorargumentsexception (E.getmessage (), args); } return establishedconnection (connection); }
Category 2: Passive connection (it means that debugger passively waits or listens for connections initiated by the target VM)
The premise is that the Target VM must start with the-AGENTLIB:JDWP=TRANSPORT=XXX,ADDRESS=YYY parameter in the following manner and generate a listening address based on the transport mode.
Step 1: The debugger obtains all Listeningconnector instances through the Virtualmachinemanager listeningconnectors () method.
Public list<listeningconnector> listeningconnectors () {ArrayList List = new ArrayList (1); List.add (New Socketlisteningconnectorimpl (this)); return list; }
Step 2: Call Listeningconnector's Startlistening () method to let the connector enter the listening state. Notifies the connector to start waiting for the correct inbound link through the Accept () method, which returns the address descriptor that the debugger is listening on, the target virtual machine automatically attach the connection to the debugger, and then returns an instance of the target VM.
Public String startlistening (map<string,? extends Connector.argument> Connectionargs) throws IOException, Illega lconnectorargumentsexception {getconnectionarguments (Connectionargs); String result = null; try {result = ((Sockettransportimpl) this.ftransport). startlistening (This.fport); } catch (IllegalArgumentException localillegalargumentexception) {throw new Illegalconnectorargumentsexception ( Connectmessages.socketlisteningconnectorimpl_listeningconnector_socket_port, "Port"); } return result; }
This article is from the "cohesion of parallel Lines" blog, please be sure to keep this source http://supercharles888.blog.51cto.com/609344/1588011
JPDA Architecture Research 19-jdi Connection module