|
|
@@ -1,8 +1,6 @@
|
|
|
-package net.ranides.demo.debugger;
|
|
|
+package net.ranides.demo.debugger.util;
|
|
|
|
|
|
import com.sun.jdi.*;
|
|
|
-import com.sun.jdi.connect.AttachingConnector;
|
|
|
-import com.sun.jdi.connect.Connector;
|
|
|
import com.sun.jdi.event.BreakpointEvent;
|
|
|
import com.sun.jdi.event.Event;
|
|
|
import com.sun.jdi.event.EventSet;
|
|
|
@@ -10,34 +8,24 @@ import com.sun.jdi.event.LocatableEvent;
|
|
|
import com.sun.jdi.request.BreakpointRequest;
|
|
|
import lombok.AccessLevel;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
+import net.ranides.demo.debugger.DiClass;
|
|
|
+import net.ranides.demo.debugger.DiConnection;
|
|
|
|
|
|
import java.util.Arrays;
|
|
|
import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
public class SimpleDebugger implements AutoCloseable {
|
|
|
|
|
|
- private VirtualMachine vm;
|
|
|
+ private DiConnection di;
|
|
|
|
|
|
public SimpleDebugger connect(String port) throws Exception {
|
|
|
- return connect("localhost", port);
|
|
|
+ di = DiConnection.connect(port);
|
|
|
+ return this;
|
|
|
}
|
|
|
|
|
|
public SimpleDebugger connect(String host, String port) throws Exception {
|
|
|
- AttachingConnector connector = Bootstrap.virtualMachineManager()
|
|
|
- .attachingConnectors()
|
|
|
- .stream()
|
|
|
- .filter(v -> v.name().equals("com.sun.jdi.SocketAttach"))
|
|
|
- .findFirst()
|
|
|
- .orElseThrow(() -> new UnsupportedOperationException("No SocketAttachingConnector found."));
|
|
|
-
|
|
|
- Map<String, Connector.Argument> args = connector.defaultArguments();
|
|
|
- args.get("hostname").setValue(host);
|
|
|
- args.get("port").setValue(port);
|
|
|
-
|
|
|
- this.vm = connector.attach(args);
|
|
|
-
|
|
|
+ di = DiConnection.connect(host, port);
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
@@ -51,22 +39,17 @@ public class SimpleDebugger implements AutoCloseable {
|
|
|
}
|
|
|
|
|
|
public BreakpointRequest breakpoint(RemoteLocation remote) throws Exception {
|
|
|
- ClassType type = vm.classesByName(remote.className)
|
|
|
- .stream()
|
|
|
- .filter(ClassType.class::isInstance)
|
|
|
- .map(ClassType.class::cast)
|
|
|
- .findAny()
|
|
|
+ DiClass type = di.types(remote.className).first()
|
|
|
.orElseThrow(() -> new IllegalArgumentException("Unknown class: " + remote.className));
|
|
|
|
|
|
- Location location = type.locationsOfLine(remote.line).get(0);
|
|
|
- BreakpointRequest breakpoint = vm.eventRequestManager().createBreakpointRequest(location);
|
|
|
+ BreakpointRequest breakpoint = type.locate(remote.line).breakpoint();
|
|
|
breakpoint.enable();
|
|
|
return breakpoint;
|
|
|
}
|
|
|
|
|
|
public <T> T loop(LoopHandler<T> handler) throws Exception {
|
|
|
EventSet eventSet;
|
|
|
- while ((eventSet = vm.eventQueue().remove()) != null) {
|
|
|
+ while ((eventSet = di.vm().eventQueue().remove()) != null) {
|
|
|
for (Event event : eventSet) {
|
|
|
try {
|
|
|
LoopContext context = new LoopContext(event);
|
|
|
@@ -79,7 +62,7 @@ public class SimpleDebugger implements AutoCloseable {
|
|
|
} catch (Exception error) {
|
|
|
throw new RuntimeException(error);
|
|
|
} finally {
|
|
|
- vm.resume();
|
|
|
+ di.vm().resume();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -93,13 +76,13 @@ public class SimpleDebugger implements AutoCloseable {
|
|
|
throw new IllegalArgumentException("Unknown variable: " + name);
|
|
|
}
|
|
|
Value mirror = frame.getValue(variable);
|
|
|
- return fromMirror(mirror);
|
|
|
+ return di.mirror().asPrimitive(mirror);
|
|
|
}
|
|
|
|
|
|
private Object call0(LocatableEvent event, String methodName, Object[] arguments) throws Exception {
|
|
|
- List<Value> input = Arrays.stream(arguments).map(this::mirrorOf).collect(Collectors.toList());
|
|
|
+ List<Value> input = Arrays.stream(arguments).map(di.mirror()::asMirror).collect(Collectors.toList());
|
|
|
Value out = call0(event, methodName, input);
|
|
|
- return fromMirror(out);
|
|
|
+ return di.mirror().asPrimitive(out);
|
|
|
}
|
|
|
|
|
|
private Value call0(LocatableEvent event, String methodName, List<? extends Value> arguments) throws Exception {
|
|
|
@@ -114,69 +97,7 @@ public class SimpleDebugger implements AutoCloseable {
|
|
|
|
|
|
@Override
|
|
|
public void close() {
|
|
|
- vm.dispose();
|
|
|
- }
|
|
|
-
|
|
|
- public Value mirrorOf(Object value) {
|
|
|
- if (value instanceof String) {
|
|
|
- return vm.mirrorOf((String) value);
|
|
|
- }
|
|
|
- if (value instanceof Integer) {
|
|
|
- return vm.mirrorOf((Integer) value);
|
|
|
- }
|
|
|
- if (value instanceof Short) {
|
|
|
- return vm.mirrorOf((Short) value);
|
|
|
- }
|
|
|
- if (value instanceof Byte) {
|
|
|
- return vm.mirrorOf((Byte) value);
|
|
|
- }
|
|
|
- if (value instanceof Long) {
|
|
|
- return vm.mirrorOf((Long) value);
|
|
|
- }
|
|
|
- if (value instanceof Float) {
|
|
|
- return vm.mirrorOf((Float) value);
|
|
|
- }
|
|
|
- if (value instanceof Double) {
|
|
|
- return vm.mirrorOf((Double) value);
|
|
|
- }
|
|
|
- if (value instanceof Boolean) {
|
|
|
- return vm.mirrorOf((Boolean) value);
|
|
|
- }
|
|
|
- if (value instanceof Character) {
|
|
|
- return vm.mirrorOf((Character) value);
|
|
|
- }
|
|
|
- throw new IllegalArgumentException("Not supported value: " + value);
|
|
|
- }
|
|
|
-
|
|
|
- public Object fromMirror(Value value) {
|
|
|
- if (value instanceof StringReference) {
|
|
|
- return ((StringReference) value).value();
|
|
|
- }
|
|
|
- if (value instanceof IntegerValue) {
|
|
|
- return ((IntegerValue) value).value();
|
|
|
- }
|
|
|
- if (value instanceof ShortValue) {
|
|
|
- return ((ShortValue) value).value();
|
|
|
- }
|
|
|
- if (value instanceof ByteValue) {
|
|
|
- return ((ByteValue) value).value();
|
|
|
- }
|
|
|
- if (value instanceof LongValue) {
|
|
|
- return ((LongValue) value).value();
|
|
|
- }
|
|
|
- if (value instanceof FloatValue) {
|
|
|
- return ((FloatValue) value).value();
|
|
|
- }
|
|
|
- if (value instanceof DoubleValue) {
|
|
|
- return ((DoubleValue) value).value();
|
|
|
- }
|
|
|
- if (value instanceof BooleanValue) {
|
|
|
- return ((BooleanValue) value).value();
|
|
|
- }
|
|
|
- if (value instanceof CharValue) {
|
|
|
- return ((CharValue) value).value();
|
|
|
- }
|
|
|
- throw new IllegalArgumentException("Not supported value: " + value);
|
|
|
+ di.vm().dispose();
|
|
|
}
|
|
|
|
|
|
public class RemoteLocation {
|
|
|
@@ -240,7 +161,7 @@ public class SimpleDebugger implements AutoCloseable {
|
|
|
return event instanceof LocatableEvent;
|
|
|
}
|
|
|
|
|
|
- public boolean matches(RemoteLocation location) throws Exception {
|
|
|
+ public boolean matches(RemoteLocation location) {
|
|
|
return isLocatable() && location.matches((LocatableEvent)event);
|
|
|
}
|
|
|
|
|
|
@@ -268,7 +189,7 @@ public class SimpleDebugger implements AutoCloseable {
|
|
|
return event;
|
|
|
}
|
|
|
|
|
|
- public boolean matches(RemoteLocation location) throws Exception {
|
|
|
+ public boolean matches(RemoteLocation location) {
|
|
|
return location.matches(event);
|
|
|
}
|
|
|
|