Skip to content

Instantly share code, notes, and snippets.

@kliu
Created January 13, 2011 14:04
Show Gist options
  • Save kliu/777890 to your computer and use it in GitHub Desktop.
Save kliu/777890 to your computer and use it in GitHub Desktop.
Make your own Prism Debuger by JPDA/JDI
package test;
import java.util.ArrayList;
import java.util.Date;
import java.util.Map;
import com.sun.jdi.Bootstrap;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.Value;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.VirtualMachineManager;
import com.sun.jdi.connect.AttachingConnector;
import com.sun.jdi.connect.Connector;
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.ModificationWatchpointEvent;
import com.sun.jdi.event.VMDeathEvent;
import com.sun.jdi.event.VMDisconnectEvent;
import com.sun.jdi.request.ClassPrepareRequest;
import com.sun.jdi.request.ModificationWatchpointRequest;
public class Debuger {
private static final String KERNEL_CLASS_NAME = "com.micromethod.common.server.kernel.KernelImpl";
private static final String STATE_CLASS_NAME = "com.micromethod.common.util.state.State";
public static void main(final String[] args) throws Exception {
final VirtualMachineManager vmManager = Bootstrap.virtualMachineManager();
AttachingConnector connector = null;
for (final Connector c : vmManager.attachingConnectors()) {
if ("com.sun.jdi.SocketAttach".equals(c.name())) {
connector = (AttachingConnector) c;
break;
}
}
final Map<String, Connector.Argument> connectorArgs = connector.defaultArguments();
final Connector.Argument pidArgument = connectorArgs.get("port");
pidArgument.setValue("8000");
final VirtualMachine vm = connector.attach(connectorArgs);
System.out.println("----------------------------------------------");
System.out.println(vm.description());
System.out.println("----------------------------------------------");
System.out.println("");
final ClassPrepareRequest reqKernel = vm.eventRequestManager().createClassPrepareRequest();
reqKernel.addClassFilter(KERNEL_CLASS_NAME);
reqKernel.setEnabled(true);
final EventQueue queue = vm.eventQueue();
boolean running = true;
while (running) {
final EventSet events = queue.remove();
for (final Event event : events) {
if (event instanceof ClassPrepareEvent) {
final ModificationWatchpointRequest modificationWatchpointRequest = vm.eventRequestManager()
.createModificationWatchpointRequest(((ClassPrepareEvent) event).referenceType().fieldByName("_state"));
modificationWatchpointRequest.setEnabled(true);
}
else if (event instanceof ModificationWatchpointEvent) {
final ModificationWatchpointEvent modEvent = (ModificationWatchpointEvent) event;
final ObjectReference oldRef = (ObjectReference) modEvent.valueCurrent();
final ObjectReference newRef = (ObjectReference) modEvent.valueToBe();
System.out.println("["
+ new Date()
+ "]# "
+ "Prism Kernel: "
+ (oldRef == null ? "\"UNKNOW\"" : oldRef.invokeMethod(((ModificationWatchpointEvent) event).thread(), vm
.classesByName(STATE_CLASS_NAME).get(0).methodsByName("name").get(0), new ArrayList<Value>(),
ObjectReference.INVOKE_NONVIRTUAL))
+ " -> "
+ (newRef == null ? "\"UNKNOW\"" : newRef.invokeMethod(((ModificationWatchpointEvent) event).thread(), vm
.classesByName(STATE_CLASS_NAME).get(0).methodsByName("name").get(0), new ArrayList<Value>(),
ObjectReference.INVOKE_NONVIRTUAL)));
}
else if (event instanceof VMDeathEvent || event instanceof VMDisconnectEvent) {
System.out.println("");
System.out.println("----------------------------------------------");
System.out.println("Prism Exit.");
System.out.println("----------------------------------------------");
running = false;
break;
}
}
events.resume();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment