Linuxea
Linuxea

Reputation: 329

A java program to debug another java program using JDI but receive nothing useful event

I have two class. One is debuggee and another one is debugger. I use debugger to debug debuggee. Here's my code:

JDIExampleDebuggee

package com.linuxea;

public class JDIExampleDebuggee {

  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);
  }
}

JDIExampleDebugger

package com.linuxea;

import com.sun.jdi.AbsentInformationException;
import com.sun.jdi.Bootstrap;
import com.sun.jdi.ClassType;
import com.sun.jdi.IncompatibleThreadStateException;
import com.sun.jdi.LocalVariable;
import com.sun.jdi.Location;
import com.sun.jdi.StackFrame;
import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.Value;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.connect.Connector.Argument;
import com.sun.jdi.connect.LaunchingConnector;
import com.sun.jdi.event.BreakpointEvent;
import com.sun.jdi.event.ClassPrepareEvent;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.EventSet;
import com.sun.jdi.event.LocatableEvent;
import com.sun.jdi.event.StepEvent;
import com.sun.jdi.request.BreakpointRequest;
import com.sun.jdi.request.ClassPrepareRequest;
import com.sun.jdi.request.StepRequest;
import java.util.Map;

public class JDIExampleDebugger<T> {

  private Class<T> debugClass;
  private int[] breakPointLines;

  public static void main(String[] args) {

    JDIExampleDebugger<JDIExampleDebuggee> debuggerInstance = new JDIExampleDebugger<>();
    debuggerInstance.debugClass = JDIExampleDebuggee.class;
    debuggerInstance.breakPointLines = new int[]{6};
    VirtualMachine vm;
    try {
      vm = debuggerInstance.connectAndLaunchVM();
      debuggerInstance.enableClassPrepareRequest(vm);
      EventSet eventSet;
      while ((eventSet = vm.eventQueue().remove()) != null) {
        for (Event event : eventSet) {
          System.out.println(event.getClass().getName());

          if (event instanceof ClassPrepareEvent) {
            debuggerInstance.setBreakPoints(vm, (ClassPrepareEvent) event);
          }
          if (event instanceof BreakpointEvent) {
            debuggerInstance.displayVariables((BreakpointEvent) event);
          }

          if (event instanceof BreakpointEvent) {
            debuggerInstance.enableStepRequest(vm, (BreakpointEvent) event);
          }

          if (event instanceof StepEvent) {
            debuggerInstance.displayVariables((StepEvent) event);
          }
          vm.resume();
        }
      }
    } catch (VMDisconnectedException e) {
      System.out.println("Virtual Machine is disconnected.");
      throw new RuntimeException(e);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void enableStepRequest(VirtualMachine vm, BreakpointEvent event) {
    // enable step request for last break point
    if (event.location().toString().
        contains(debugClass.getName() + ":" + breakPointLines[breakPointLines.length - 1])) {
      StepRequest stepRequest = vm.eventRequestManager()
          .createStepRequest(event.thread(), StepRequest.STEP_LINE, StepRequest.STEP_OVER);
      stepRequest.enable();
    }
  }

  public VirtualMachine connectAndLaunchVM() throws Exception {

    LaunchingConnector launchingConnector = Bootstrap.virtualMachineManager()
        .defaultConnector();
    Map<String, Argument> arguments = launchingConnector.defaultArguments();
    arguments.get("main").setValue(debugClass.getName());
    return launchingConnector.launch(arguments);
  }

  public void enableClassPrepareRequest(VirtualMachine vm) {
    ClassPrepareRequest classPrepareRequest = vm.eventRequestManager().createClassPrepareRequest();
    classPrepareRequest.addClassFilter(debugClass.getName());
    classPrepareRequest.enable();
  }

  public void setBreakPoints(VirtualMachine vm, ClassPrepareEvent event)
      throws AbsentInformationException {
    ClassType classType = (ClassType) event.referenceType();
    for (int lineNumber : breakPointLines) {
      Location location = classType.locationsOfLine(lineNumber).get(0);
      BreakpointRequest bpReq = vm.eventRequestManager().createBreakpointRequest(location);
      bpReq.enable();
    }
  }

  public void displayVariables(LocatableEvent event) throws IncompatibleThreadStateException,
      AbsentInformationException {
    StackFrame stackFrame = event.thread().frame(0);
    if (stackFrame.location().toString().contains(debugClass.getName())) {
      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());
      }
    }
  }

}

This is output:

com.sun.tools.jdi.EventSetImpl$VMStartEventImpl
com.sun.tools.jdi.EventSetImpl$VMDeathEventImpl
com.sun.tools.jdi.EventSetImpl$VMDisconnectEventImpl
Virtual Machine is disconnected.
Exception in thread "main" java.lang.RuntimeException: com.sun.jdi.VMDisconnectedException
    at com.linuxea.JDIExampleDebugger.main(JDIExampleDebugger.java:64)
Caused by: com.sun.jdi.VMDisconnectedException
    at com.sun.tools.jdi.EventQueueImpl.removeUnfiltered(EventQueueImpl.java:199)
    at com.sun.tools.jdi.EventQueueImpl.remove(EventQueueImpl.java:96)
    at com.sun.tools.jdi.EventQueueImpl.remove(EventQueueImpl.java:82)
    at com.linuxea.JDIExampleDebugger.main(JDIExampleDebugger.java:41)

Process finished with exit code 1

As you can see there is nothing useful event. The target VM is start but stop immediately.

I want to learn JDI using this tutorial. The code is learn from java-debug-interface.

I try many times but could not find out anything wrong.

The tutorial looks simple.

Upvotes: 0

Views: 237

Answers (1)

Related Questions