public synchronized VirtualMachine createVirtualMachine( Connection connection, Process process) throws IOException { if (!connection.isOpen()) { throw new IllegalStateException("connection is not open"); } VirtualMachine vm; try { vm = new VirtualMachineImpl(this, connection, process, ++vmSequenceNumber); } catch (VMDisconnectedException e) { throw new IOException(e.getMessage()); } targets.add(vm); return vm; }
@Override public Connection accept(ListenKey listenKey, long attachTimeout, long handshakeTimeout) throws IOException { if (attachTimeout > 0) { if (attachTimeout > Integer.MAX_VALUE) { attachTimeout = Integer.MAX_VALUE; // approx 25 days! } fServerSocket.setSoTimeout((int) attachTimeout); } Socket socket; try { socket = fServerSocket.accept(); } catch (SocketTimeoutException e) { throw new TransportTimeoutException(); } InputStream input = socket.getInputStream(); OutputStream output = socket.getOutputStream(); performHandshake(input, output, handshakeTimeout); return new SocketConnection(socket, input, output); }
TargetVM(VirtualMachineImpl vm, Connection connection) { this.vm = vm; this.connection = connection; this.readerThread = new Thread(vm.threadGroupForJDI(), this, "JDI Target VM Interface"); this.readerThread.setDaemon(true); }
public VirtualMachine launch(Map<String, ? extends Connector.Argument> arguments) throws IOException, IllegalConnectorArgumentsException, VMStartException { /* * Get the class name that we are to execute */ String className = ((StringArgumentImpl)arguments.get(ARG_NAME)).value(); if (className.length() == 0) { throw new IllegalConnectorArgumentsException("class name missing", ARG_NAME); } /* * Listen on an emperical port; launch the debuggee; wait for * for the debuggee to connect; stop listening; */ TransportService.ListenKey key = ts.startListening(); String exe = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"; String cmd = exe + " -Xdebug -Xrunjdwp:transport=dt_socket,timeout=15000,address=" + key.address() + " -classpath " + System.getProperty("test.classes") + " " + className; Process process = Runtime.getRuntime().exec(cmd); Connection conn = ts.accept(key, 30*1000, 9*1000); ts.stopListening(key); /* * Debugee is connected - return the virtual machine mirror */ return Bootstrap.virtualMachineManager().createVirtualMachine(conn); }
/** * Attach to a target VM using the specified address and Connector arguments. */ public VirtualMachine attach(String address, Map<String, ? extends Connector.Argument> args) throws IOException, IllegalConnectorArgumentsException { String ts = argument(ARG_TIMEOUT, args).value(); int timeout = 0; if (ts.length() > 0) { timeout = Integer.decode(ts).intValue(); } Connection connection = transportService.attach(address, timeout, 0); return Bootstrap.virtualMachineManager().createVirtualMachine(connection); }
@Override public Connection attach(String address, long attachTimeout, long handshakeTimeout) throws IOException { String[] strings = address.split(":"); //$NON-NLS-1$ String host = "localhost"; //$NON-NLS-1$ int port = 0; if (strings.length == 2) { host = strings[0]; port = Integer.parseInt(strings[1]); } else { port = Integer.parseInt(strings[0]); } return attach(host, port, attachTimeout, handshakeTimeout); }
VirtualMachineImpl(VirtualMachineManager manager, Connection connection, Process process, int sequenceNumber) { super(null); // Can't use super(this) vm = this; this.vmManager = (VirtualMachineManagerImpl)manager; this.process = process; this.sequenceNumber = sequenceNumber; /* Create ThreadGroup to be used by all threads servicing * this VM. */ threadGroupForJDI = new ThreadGroup(vmManager.mainGroupForJDI(), "JDI [" + this.hashCode() + "]"); /* * Set up a thread to communicate with the target VM over * the specified transport. */ target = new TargetVM(this, connection); /* * Set up a thread to handle events processed internally * the JDI implementation. */ EventQueueImpl internalEventQueue = new EventQueueImpl(this, target); new InternalEventHandler(this, internalEventQueue); /* * Initialize client access to event setting and handling */ eventQueue = new EventQueueImpl(this, target); eventRequestManager = new EventRequestManagerImpl(this); target.start(); /* * Many ids are variably sized, depending on target VM. * Find out the sizes right away. */ JDWP.VirtualMachine.IDSizes idSizes; try { idSizes = JDWP.VirtualMachine.IDSizes.process(vm); } catch (JDWPException exc) { throw exc.toJDIException(); } sizeofFieldRef = idSizes.fieldIDSize; sizeofMethodRef = idSizes.methodIDSize; sizeofObjectRef = idSizes.objectIDSize; sizeofClassRef = idSizes.referenceTypeIDSize; sizeofFrameRef = idSizes.frameIDSize; /** * Set up requests needed by internal event handler. * Make sure they are distinguished by creating them with * an internal event request manager. * * Warning: create events only with SUSPEND_NONE policy. * In the current implementation other policies will not * be handled correctly when the event comes in. (notfiySuspend() * will not be properly called, and if the event is combined * with external events in the same set, suspend policy is not * correctly determined for the internal vs. external event sets) */ internalEventRequestManager = new EventRequestManagerImpl(this); EventRequest er = internalEventRequestManager.createClassPrepareRequest(); er.setSuspendPolicy(EventRequest.SUSPEND_NONE); er.enable(); er = internalEventRequestManager.createClassUnloadRequest(); er.setSuspendPolicy(EventRequest.SUSPEND_NONE); er.enable(); /* * Tell other threads, notably TargetVM, that initialization * is complete. */ notifyInitCompletion(); }
/** * Accept a connection from a debuggee and handshake with it. */ public Connection accept(ListenKey listener, long acceptTimeout, long handshakeTimeout) throws IOException { if (acceptTimeout < 0 || handshakeTimeout < 0) { throw new IllegalArgumentException("timeout is negative"); } if (!(listener instanceof SocketListenKey)) { throw new IllegalArgumentException("Invalid listener"); } ServerSocket ss; // obtain the ServerSocket from the listener - if the // socket is closed it means the listener is invalid synchronized (listener) { ss = ((SocketListenKey)listener).socket(); if (ss.isClosed()) { throw new IllegalArgumentException("Invalid listener"); } } // from here onwards it's possible that the ServerSocket // may be closed by a call to stopListening - that's okay // because the ServerSocket methods will throw an // IOException indicating the socket is closed. // // Additionally, it's possible that another thread calls accept // with a different accept timeout - that creates a same race // condition between setting the timeout and calling accept. // As it is such an unlikely scenario (requires both threads // to be using the same listener we've chosen to ignore the issue). ss.setSoTimeout((int)acceptTimeout); Socket s; try { s = ss.accept(); } catch (SocketTimeoutException x) { throw new TransportTimeoutException("timeout waiting for connection"); } // handshake here handshake(s, handshakeTimeout); return new SocketConnection(s); }
Connection connection() { return connection; }
synchronized void notifyOfConnection(Connection connection) { this.connection = connection; notify(); }
public VirtualMachine createVirtualMachine(Connection connection) throws IOException { return createVirtualMachine(connection, null); }
VirtualMachineImpl(VirtualMachineManager manager, Connection connection, Process process, int sequenceNumber) { super(null); // Can't use super(this) vm = this; this.vmManager = (VirtualMachineManagerImpl)manager; this.process = process; this.sequenceNumber = sequenceNumber; /* Create ThreadGroup to be used by all threads servicing * this VM. */ threadGroupForJDI = new ThreadGroup(vmManager.mainGroupForJDI(), "JDI [" + this.hashCode() + "]"); /* * Set up a thread to communicate with the target VM over * the specified transport. */ target = new TargetVM(this, connection); /* * Set up a thread to handle events processed internally * the JDI implementation. */ EventQueueImpl internalEventQueue = new EventQueueImpl(this, target); new InternalEventHandler(this, internalEventQueue); /* * Initialize client access to event setting and handling */ eventQueue = new EventQueueImpl(this, target); eventRequestManager = new EventRequestManagerImpl(this); target.start(); /* * Many ids are variably sized, depending on target VM. * Find out the sizes right away. */ JDWP.VirtualMachine.IDSizes idSizes; try { idSizes = JDWP.VirtualMachine.IDSizes.process(vm); } catch (JDWPException exc) { throw exc.toJDIException(); } sizeofFieldRef = idSizes.fieldIDSize; sizeofMethodRef = idSizes.methodIDSize; sizeofObjectRef = idSizes.objectIDSize; sizeofClassRef = idSizes.referenceTypeIDSize; sizeofFrameRef = idSizes.frameIDSize; sizeofModuleRef = idSizes.objectIDSize; /** * Set up requests needed by internal event handler. * Make sure they are distinguished by creating them with * an internal event request manager. * * Warning: create events only with SUSPEND_NONE policy. * In the current implementation other policies will not * be handled correctly when the event comes in. (notfiySuspend() * will not be properly called, and if the event is combined * with external events in the same set, suspend policy is not * correctly determined for the internal vs. external event sets) */ internalEventRequestManager = new EventRequestManagerImpl(this); EventRequest er = internalEventRequestManager.createClassPrepareRequest(); er.setSuspendPolicy(EventRequest.SUSPEND_NONE); er.enable(); er = internalEventRequestManager.createClassUnloadRequest(); er.setSuspendPolicy(EventRequest.SUSPEND_NONE); er.enable(); /* * Tell other threads, notably TargetVM, that initialization * is complete. */ notifyInitCompletion(); }
public Connection attach(String hostname, int port, long attachTimeout, long handshakeTimeout) throws IOException { return service.attach(hostname, port, attachTimeout, handshakeTimeout); }
public Connection accept(long attachTimeout, long handshakeTimeout) throws IOException { return service.accept(fListenKey, attachTimeout, handshakeTimeout); }
public VirtualMachine createVirtualMachine(Connection connection, Process process) throws IOException { VirtualMachineManager pvmm = Bootstrap.virtualMachineManager(); return F3Wrapper.wrap(pvmm.createVirtualMachine(connection, process)); }
public VirtualMachine createVirtualMachine(Connection connection) throws IOException { VirtualMachineManager pvmm = Bootstrap.virtualMachineManager(); return F3Wrapper.wrap(pvmm.createVirtualMachine(connection)); }