2017-12-22 15 views
1

java debug interface을 사용하여 디버거를 빌드하려고합니다.
내 목표는 중단 점을 설정하고 변수 값을 얻는 것입니다.
내가 찾은 답변에 가까운 this 답변을 찾았습니다. 다음 인터페이스를 사용해야한다는 것을 이해합니다. - VirtualMachineManager, LaunchingConnector, ClassPrepareEvent, ClassPrepareRequest. 하지만 특정 줄에 중단 점을 설정하고 변수의 값을 얻는 방법이나 인터페이스를 사용해야하는 순서를 알아낼 수 없습니다. 아래 코드의 예를 들어 jdi로 간단한 디버거를 빌드하여 중단 점을 설정하고 변수 값을 검색하십시오.

, 어떻게 내가 라인 a = 12에 디버그 포인트를 설정 생각하고 변수 S

import java.io.*; 

class Hello { 

    public static void main(String args[]) { 
    String S = "Hello World"; 
    int a = 12; 
    } 
} 

jdi 같은 내가 얻을 값으로 실행 진행 할 또는 방법의 폐점 때 S

+0

사용 event.referenceType()를 호출하는 방법입니다. locationsOfLine ("원하는 행 번호") classpreparedevent와 함께. 그런 다음 위치 객체를 가져온 후 중단 점 요청을 만듭니다. – rainyday

답변

1

이이 article이 유용하다는 것을 알았습니다. 여기 도 도움이 될 example입니다.

또는 다음 project

를 확인하실 수 있습니다 여기에 당신이 연주 할 예제 코드입니다.

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package jdidebugger; 

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.Method; 
import com.sun.jdi.StackFrame; 
import com.sun.jdi.ThreadReference; 
import com.sun.jdi.Value; 
import com.sun.jdi.VirtualMachine; 
import com.sun.jdi.VirtualMachineManager; 
import com.sun.jdi.connect.Connector; 
import com.sun.jdi.connect.IllegalConnectorArgumentsException; 
import com.sun.jdi.connect.LaunchingConnector; 
import com.sun.jdi.connect.VMStartException; 
import com.sun.jdi.event.BreakpointEvent; 
import com.sun.jdi.event.ClassPrepareEvent; 
import com.sun.jdi.event.Event; 
import com.sun.jdi.event.EventIterator; 
import com.sun.jdi.event.EventQueue; 
import com.sun.jdi.event.EventSet; 
import com.sun.jdi.request.BreakpointRequest; 
import com.sun.jdi.request.ClassPrepareRequest; 
import com.sun.jdi.request.EventRequestManager; 
import java.io.IOException; 
import java.util.List; 
import java.util.Map; 
import java.util.function.Consumer; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

/** 
* 
* @author bonnie 
*/ 
public class JdiDebugger { 

    /** 
    * @param options 
    * @param main 
    * @param classPattern 
    * @param methodName 
    * @param lineNumber 
    * @throws java.io.IOException 
    * @throws com.sun.jdi.connect.IllegalConnectorArgumentsException 
    * @throws com.sun.jdi.connect.VMStartException 
    * @throws java.lang.InterruptedException 
    * @throws com.sun.jdi.AbsentInformationException 
    * @throws com.sun.jdi.IncompatibleThreadStateException 
    */ 
    public static void onMethodExit(String options, String main, String classPattern, String methodName) throws IOException, IllegalConnectorArgumentsException, VMStartException, InterruptedException, AbsentInformationException, IncompatibleThreadStateException { 

     // create and launch a virtual machine 
     VirtualMachineManager vmm = Bootstrap.virtualMachineManager(); 
     LaunchingConnector lc = vmm.defaultConnector(); 
     Map<String, Connector.Argument> env = lc.defaultArguments(); 
     env.get("options").setValue(options); 
     env.get("main").setValue(main); 
     VirtualMachine vm = lc.launch(env); 

     // create a class prepare request 
     EventRequestManager erm = vm.eventRequestManager(); 
     ClassPrepareRequest r = erm.createClassPrepareRequest(); 
     r.addClassFilter(classPattern); 
     r.enable(); 

     EventQueue queue = vm.eventQueue(); 
     while (true) { 
      EventSet eventSet = queue.remove(); 
      EventIterator it = eventSet.eventIterator(); 
      while (it.hasNext()) { 
       Event event = it.nextEvent(); 
       if (event instanceof ClassPrepareEvent) { 
        ClassPrepareEvent evt = (ClassPrepareEvent) event; 
        ClassType classType = (ClassType) evt.referenceType(); 

        classType.methodsByName(methodName).forEach(new Consumer<Method>() { 
         @Override 
         public void accept(Method m) { 
          List<Location> locations = null; 
          try { 
           locations = m.allLineLocations(); 
          } catch (AbsentInformationException ex) { 
           Logger.getLogger(JdiDebuggerOld.class.getName()).log(Level.SEVERE, null, ex); 
          } 
          // get the last line location of the function and enable the 
          // break point 
          Location location = locations.get(locations.size() - 1); 
          BreakpointRequest bpReq = erm.createBreakpointRequest(location); 
          bpReq.enable(); 
         } 
        }); 

       } 
       if (event instanceof BreakpointEvent) { 
        // disable the breakpoint event 
        event.request().disable(); 

        ThreadReference thread = ((BreakpointEvent) event).thread(); 
        StackFrame stackFrame = thread.frame(0); 

        // print all the visible variables with the respective values 
        Map<LocalVariable, Value> visibleVariables = (Map<LocalVariable, Value>) stackFrame.getValues(stackFrame.visibleVariables()); 
        for (Map.Entry<LocalVariable, Value> entry : visibleVariables.entrySet()) { 
         System.out.println(entry.getKey() + ":" + entry.getValue()); 
        } 
       } 
       vm.resume(); 
      } 
     } 
    } 
} 

는이 당신이 방법을

new jdiDebugger().onMehtodeExit("-cp <whatever your class path is>", "<name of the class that contains the main method>", "<the name of the class that you wish to debug>", "<the name of the method that you want to debug>");