1

我想在应用程序开始运行之前在应用程序中设置一个断点,这样我就可以确保应用程序在启动时不会通过断点。

为了设置断点,您需要执行以下操作:

EventRequestManager reqMan = vm.eventRequestManager();
BreakpointRequest bpReq = reqMan.createBreakpointRequest(locationForBreakpoint);
bpReq.enable();

为了获取断点的位置,您可以执行以下操作:

Method method = location.method();
List<Location> locations = method.locationsOfLine(55);
Location locationForBreakpoint = locations.get(0);

为了获得方法,您可以执行以下操作:

classType.concreteMethodByName(methodNname, String signature)

但是,为了获得该类类型,您似乎需要一个似乎需要运行 JVM 的 ObjectReference。

有没有办法在应用程序JVM运行之前设置断点,以确保在应用程序启动期间不通过断点?

4

1 回答 1

1

首先,使用LaunchingConnector 启动目标程序以取回目标虚拟机。

VirtualMachineManager vmm = Bootstrap.virtualMachineManager();
LaunchingConnector lc = vmm.launchingConnectors().get(0);
// Equivalently, can call:
// LaunchingConnector lc = vmm.defaultConnector();

Map<String, Connector.Argument> env = lc.defaultArguments();
env.get("main").setValue("p.DebugDummy");
env.get("suspend").setValue("true");
env.get("home").setValue("C:/Program Files/Java/jdk1.7.0_51");
VirtualMachine vm = lc.launch(env);

(根据您的需要更改环境值,但请记住使用 启动目标 VM suspended=true)。
有了这个虚拟机,你就可以使用ClassPrepareRequest拦截ClassPrepareEvent

ClassPrepareRequest r = reqMan.createClassPrepareRequest();
r.addClassFilter("myclasses.SampleClass");
r.enable();

创建ClassPrepareEvent处理程序

 executor.execute(()->    {
    try {
      while(true)
      {
          EventQueue eventQueue = vm.eventQueue();
          EventSet eventSet = eventQueue.remove();
          EventIterator eventIterator = eventSet.eventIterator();
          if (eventIterator.hasNext()) {
            Event event = eventIterator.next();
            if(event instanceof ClassPrepareEvent) {
              ClassPrepareEvent evt = (ClassPrepareEvent) event;
              ClassType classType = (ClassType) evt.referenceType();
              List<Location> locations = referenceType.locationsOfLine(55);
              Location locationForBreakpoint = locations.get(0);

              vm.resume();
            }
          }
        }
    } catch (InterruptedException | AbsentInformationException | IncompatibleThreadStateException e) {
      e.printStackTrace();
    }
  }

然后通过调用vm.resume()来恢复目标 VM 以运行程序。我希望这能解决你的问题。

于 2016-02-16T07:53:29.070 回答