How can I add a ClassPreparedEvent to the EventQueue of my jdi vm

48 views Asked by At

I am trying to code a debugger for a school project, so I can go through the code step by step and possibly skip over some methods, so far I have tried multiple approaches with the com.sun.jdi package but nothing has worked so far, as my jdi Event queue does not include a class-prepared event so I cannot set the breakpoints automatically. Is there a way around this, I have attached my code below. Different approaches or solutions to the problem are welcome.

Thank you

This is my debugger class so far.

package JPIDebugger;

import java.util.Map;

import com.sun.jdi.connect.Connector;
import com.sun.jdi.connect.LaunchingConnector;
import com.sun.jdi.event.*;
import com.sun.jdi.request.BreakpointRequest;
import com.sun.jdi.request.ClassPrepareRequest;
import com.sun.jdi.*;

public class JPIDebuggerClass {

    public static void main(String[] args) throws Exception {
        int[] breakPointLines = {6, 9};
        //VirtualMachine vm = null;
        try {
            // Starting the VM
            LaunchingConnector launchingConnector = Bootstrap.virtualMachineManager()
                    .defaultConnector();
            Map<String, Connector.Argument> arguments = launchingConnector.defaultArguments();
            arguments.get("main").setValue("JPIDebugger.Debuggee");
            VirtualMachine vm = launchingConnector.launch(arguments);

            // Setting up the class prepare request
            ClassPrepareRequest classPrepareRequest = vm.eventRequestManager().createClassPrepareRequest();
            classPrepareRequest.addClassFilter("JPIDebugger.Debuggee");
            classPrepareRequest.enable();
            // The classPrepareRequest should have put a ClassPreparedEvent in the event queue

            while (true) {
                EventQueue eventQueue = vm.eventQueue();
                EventSet eventSet = eventQueue.remove();
                EventIterator eventIterator = eventSet.eventIterator();
                System.out.println(eventIterator.toString() + " Event Set is received.");
                while (eventIterator.hasNext()) {
                    Event event = eventIterator.next();
                    System.out.println(event.toString() + " is the event");
                    if (event instanceof ClassPrepareEvent) {
                        System.out.println("Class is prepared");
                        ClassType classType = (ClassType) ((ClassPrepareEvent) event).referenceType();
                        for (int lineNumber : breakPointLines) {
                            Location location = classType.locationsOfLine(lineNumber).get(0);
                            BreakpointRequest bpReq = vm.eventRequestManager().createBreakpointRequest(location);
                            bpReq.enable();
                        }
                    }
                    if (event instanceof BreakpointEvent) {
                        System.out.println("Breakpoint is hit");
                        LocatableEvent locatableEvent = (LocatableEvent) event;
                        StackFrame stackFrame = locatableEvent.thread().frame(0);
                        if (stackFrame.location().toString().contains("JPIDebugger.Debuggee")) {
                            Map<LocalVariable, Value> visibleVariables = stackFrame
                                    .getValues(stackFrame.visibleVariables());
                            System.out.println("Variables at " + stackFrame.location().toString() + " > ");
                            for (Map.Entry<LocalVariable, Value> entry : visibleVariables.entrySet()) {
                                System.out.println(entry.getKey().name() + " = " + entry.getValue());
                            }
                        }
                    }
                    vm.resume();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

This is the Debuggee class, that I am trying to "Debug" and set breakpoints in.

package JPIDebugger;

public class Debuggee {

    public static void main(String[] args) {
        String jpda = "Java Platform Debugger Architecture";
        System.out.println("Hi Everyone, Welcome to " + jpda); // add a break point here

        String jdi = "Java Debug Interface"; // add a break point here and also stepping in here
        String text = "Today, we'll dive into " + jdi;
        System.out.println(text);
    }

}

The Output I am getting is:

com.sun.tools.jdi.EventSetImpl$Itr@2957fcb0 Event Set is received.
VMStartEvent in thread main is the event
com.sun.tools.jdi.EventSetImpl$Itr@3b764bce Event Set is received.
VMDeathEvent is the event
com.sun.tools.jdi.EventSetImpl$Itr@45fe3ee3 Event Set is received.
VMDisconnectEvent is the event
com.sun.jdi.VMDisconnectedException
    at jdk.jdi/com.sun.tools.jdi.EventQueueImpl.removeUnfiltered(EventQueueImpl.java:200)
    at jdk.jdi/com.sun.tools.jdi.EventQueueImpl.remove(EventQueueImpl.java:97)
    at jdk.jdi/com.sun.tools.jdi.EventQueueImpl.remove(EventQueueImpl.java:83)
    at JPIDebugger.JPIDebuggerClass.main(JPIDebuggerClass.java:31)

0

There are 0 answers