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)

ただし、そのclassTypeを取得するには、実行中の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)。
この VM を使用して、 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 に答える