Package st.gravel.support.jvm.debugger

Source Code of st.gravel.support.jvm.debugger.VMTargetStarter

package st.gravel.support.jvm.debugger;

import java.io.IOException;
import java.io.PrintStream;
import java.lang.ProcessBuilder.Redirect;
import java.util.List;

import com.sun.jdi.IncompatibleThreadStateException;
import com.sun.jdi.Method;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.event.BreakpointEvent;
import com.sun.jdi.event.ClassPrepareEvent;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.EventQueue;
import com.sun.jdi.event.EventSet;
import com.sun.jdi.event.VMDeathEvent;
import com.sun.jdi.event.VMDisconnectEvent;
import com.sun.jdi.request.BreakpointRequest;
import com.sun.jdi.request.ClassPrepareRequest;

public class VMTargetStarter {
  private static int nextPort = 8000;
  private VMTargetStarter(int debugPort) {
    super();
    this.debugPort = debugPort;
  }

  private final int debugPort;

  public Process startSecondJVM(Class<?> mainClassToStart) throws IOException {
    String separator = System.getProperty("file.separator");
    String classpath = System.getProperty("java.class.path");
    String path = System.getProperty("java.home") + separator + "bin"
        + separator + "java";

    ProcessBuilder processBuilder = new ProcessBuilder(path, "-Xdebug",
        "-Xrunjdwp:transport=dt_socket,address=" + debugPort
            + ",server=y,suspend=y", "-cp", classpath,
        mainClassToStart.getCanonicalName());
    processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
    final Process process = processBuilder.start();
    Thread closeChildThread = new Thread() {
      public void run() {
        process.destroy();
      }
    };
    Runtime.getRuntime().addShutdownHook(closeChildThread);
    return process;

  }

  public static void sleep(int millis) {
    try {
      Thread.sleep(millis);
    } catch (InterruptedException ex) {
      Thread.currentThread().interrupt();
    }
  }

  public VMRemoteTarget createJVM() throws IOException, InterruptedException,
      IncompatibleThreadStateException {
    Process process = startSecondJVM(VMLocalTarget.class);
    sleep(90);
    // connect
    VirtualMachine vm = new VMAcquirer().connect(debugPort);

    ClassPrepareRequest createClassPrepareRequest = vm
        .eventRequestManager().createClassPrepareRequest();
    createClassPrepareRequest.addClassFilter(VMLocalTarget.class.getName());
    createClassPrepareRequest.enable();
   
    vm.resume();

    List<ThreadReference> allThreads = vm.allThreads();
    for (ThreadReference threadReference : allThreads) {
      System.out.println(threadReference+" isSuspended: "+threadReference.isSuspended()+" suspendCount: "+threadReference.suspendCount());
    }

    // process events
    EventQueue eventQueue = vm.eventQueue();
    while (true) {
      EventSet eventSet = eventQueue.remove();
      for (Event event : eventSet) {
        if (event instanceof ClassPrepareEvent) {
          event.request().disable();
          installHaltPoint(vm);
        }
        if (event instanceof VMDeathEvent
            || event instanceof VMDisconnectEvent) {
          return null;
        }
        if (event instanceof BreakpointEvent) {
          event.request().disable();
          ThreadReference thread = ((BreakpointEvent) event).thread();
          return new VMRemoteTarget(process, vm, thread, debugPort);
        }
      }
      eventSet.resume();
    }
  }

  private void installHaltPoint(VirtualMachine vm) {
    List<ReferenceType> targetClasses = vm
        .classesByName(VMLocalTarget.class.getName());
    ReferenceType classRef = targetClasses.get(0);
    Method meth = classRef.methodsByName("haltPoint").get(0);
    BreakpointRequest req = vm.eventRequestManager()
        .createBreakpointRequest(meth.location());
    req.setSuspendPolicy(BreakpointRequest.SUSPEND_EVENT_THREAD);
    req.enable();
  }

  public static VMRemoteTarget newRemote(int port) {
    try {
      return new VMTargetStarter(port).createJVM();
    } catch (IOException | InterruptedException
        | IncompatibleThreadStateException e) {
      throw new RuntimeException(e);
    }
  }

  public static VMRemoteTarget newRemote() {
    return newRemote(nextPort++);
  }

}
TOP

Related Classes of st.gravel.support.jvm.debugger.VMTargetStarter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.