package st.gravel.support.jvm.debugger;
import com.sun.jdi.IncompatibleThreadStateException;
import com.sun.jdi.IntegerValue;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.Value;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.EventQueue;
import com.sun.jdi.event.EventSet;
import com.sun.jdi.event.ExceptionEvent;
import com.sun.jdi.event.VMDeathEvent;
import com.sun.jdi.event.VMDisconnectEvent;
public class VMRemoteTarget extends VMRemoteInstance {
int debugPort;
private VirtualMachine vm;
public VMRemoteTarget(Process process, VirtualMachine vm,
ThreadReference thread, int debugPort)
throws IncompatibleThreadStateException {
super(thread.frames().get(0).thisObject());
this.vm = vm;
this.process = process;
this.bootThread = thread;
this.debugPort = debugPort;
startEventLoop();
}
private void startEventLoop() {
// trapExceptions();
new Thread(new Runnable() {
@Override
public void run() {
try {
eventLoop();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}).start();
}
private void trapExceptions() {
ReferenceType referenceType = vm.classesByName("java.lang.Throwable").get(0);
vm.eventRequestManager().createExceptionRequest(referenceType, true, true).enable();
}
private Process process;
ThreadReference bootThread;
private void eventLoop() throws InterruptedException {
System.out.println("eventLoop started");
EventQueue eventQueue = vm.eventQueue();
boolean isRunning = true;
while (isRunning) {
EventSet eventSet = eventQueue.remove();
boolean mayResume = true;
for (Event event : eventSet) {
System.out.println(event);
if (event instanceof VMDeathEvent
|| event instanceof VMDisconnectEvent) {
isRunning = false;
} else if (event instanceof ExceptionEvent) {
mayResume = false;
}
}
if (mayResume) eventSet.resume();
}
}
public int add(int x, int y) throws Throwable {
Value resultMirror = invokeMethod("add", vm.mirrorOf(x), vm.mirrorOf(y));
return ((IntegerValue) resultMirror).intValue();
}
public void ping() throws Throwable {
invokeMethod("ping");
}
public ObjectReference evaluateForked(String source) throws Throwable {
return (ObjectReference) invokeMethod("evaluateForked", vm.mirrorOf(source));
}
@Override
protected int debugPort() {
return debugPort;
}
@Override
protected ThreadReference bootThread() {
return bootThread;
}
@Override
protected VirtualMachine vm() {
return vm;
}
}