2014-02-09 4 views
4

그래서 JDI에 자신을 맞이하려고합니다. 다음JDI 실행 커넥터를 설정하는 방법은 무엇입니까?

-agentlib:jdwp=transport=dt_socket,server=y,address=8000 

및 취부 커넥터를 사용하여 연결 설정 내 디버거 시작 :

VirtualMachineManager vmm = Bootstrap.virtualMachineManager(); 
AttachingConnector ac = vmm.attachingConnectors().get(0); 
Map<String, Connector.Argument> env = ac.defaultArguments(); 
env.get("port").setValue("8000"); 
env.get("hostname").setValue("localhost"); 
VirtualMachine vm = ac.attach(env); 
을 나는 명령을 먼저 VM과 디버를 시작하여 내 debugee 프로그램에 내 디버거 응용 프로그램을 후킹 이미 성공

하지만 이제 디버거 응용 프로그램을 디버그 프로그램 자체를 시작하고 싶습니다. 이 경우 런칭 커넥터를 사용해야한다는 것을 알고 있습니다. 그래서 이것을 시도 :

VirtualMachineManager vmm = Bootstrap.virtualMachineManager(); 
LaunchingConnector lc = vmm.launchingConnectors().get(0); 
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); 

그러나이 응용 프로그램을 시작할 때 내 debiane 프로그램이 시작되지 않습니다. 위에서 보여준 코드에 대한 일련의 후속 코드가 있음에도 불구하고 예외 나 기타 사항은 없습니다. stuff like :

// A single implementor of this interface exists in a particuar VM 
    EventRequestManager mgr = vm.eventRequestManager(); 

    // suspend VM 
    vm.suspend(); 

    // lookup main thread 
    ThreadReference mainThread = null; 
    List<ThreadReference> threads = vm.allThreads(); 
    for (ThreadReference thread : threads) { 
     if ("main".equals(thread.name())) { 
      mainThread = thread; 
      break; 
     } 
    } 

    // resume 
    vm.resume(); 
    mainThread.resume(); 

    // There is one instance of EventQueue assigned to a particular 
    // VirtualMachine. 
    EventQueue eventQueue = vm.eventQueue(); 

    // Waits for start event. 
    WAIT_FOR_START: do { 
     EventSet eventSet = eventQueue.remove(); 
     EventIterator eventIterator = eventSet.eventIterator(); 
     while (eventIterator.hasNext()) { 
      Event event = eventIterator.next(); 
      if (event instanceof VMStartEvent) { 
       System.out.println("VMStartEvent."); 
       break WAIT_FOR_START; 
      } 
     } 
    } while (true); 

    System.out.println("GO..."); 

모두 잘 돌아갑니다. 예외가없고 모든 sysouts (GO ... 등)도 없습니다. 상당히 이상하게 느껴집니다. 분명히 메인 스레드와 VMStartEvent를 찾습니다. 하지만 내 디버거가이 모든 것을 자체적으로 수행하고 있다고 생각합니까? 나는이 모든 메소드 호출이 무엇을하는지 정말로 이해하지 못했을 까봐 두렵다.

내 질문 : 내 디버거 프로그램이 시작되지 않는 이유는 무엇입니까?

내가 설정은 "기본"인수 한 이상 당신이 볼 수 있듯이 :

env.get("main").setValue("p.DebugDummy"); 

내 디버거 응용 프로그램이 같은 패키지 (P)입니다. 그래서 그게 정확해야합니까? 하지만 분명히 여기서 뭔가 잘못하고 있습니다. 어떤 아이디어?

감사합니다.

답변

1

아마 하위 프로세스 stdin/stdout 스트림을 처리하지 않기 때문일 수 있습니다. 이 프로젝트를 처리하는 JDI 스크립팅 프로젝트에 VMLauncher 유틸리티 클래스가 있습니다. 관련 코드 :

public VirtualMachine safeStart() 
    throws IOException, 
      IllegalConnectorArgumentsException, 
      VMStartException 
{ 
    VirtualMachineManager vmm = Bootstrap.virtualMachineManager(); 
    LaunchingConnector connector = vmm.defaultConnector(); 
    Map<String, Argument> cArgs = connector.defaultArguments(); 
    cArgs.get("options").setValue(options); 
    cArgs.get("main").setValue(main); 
    final VirtualMachine vm = connector.launch(cArgs); 

    final Thread outThread = redirect("Subproc stdout", 
             vm.process().getInputStream(), 
             out); 
    final Thread errThread = redirect("Subproc stderr", 
             vm.process().getErrorStream(), 
             err); 
    if(killOnShutdown) { 
     Runtime.getRuntime().addShutdownHook(new Thread() { 
      public void run() { 
       outThread.interrupt(); 
       errThread.interrupt(); 
       vm.process().destroy(); 
      } 
     }); 
    } 

    return vm; 
} 

private Thread redirect(String name, InputStream in, OutputStream out) { 
    Thread t = new StreamRedirectThread(name, in, out); 
    t.setDaemon(true); 
    t.start(); 
    return t; 
} 
0

LaunchingConnector에서 클래스 경로를 설정 했습니까?

env.get("options").setValue("-cp " + 
    "/my-project/target/classes:" + 
    "/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/lib/tools.jar:" + 
    "");