【问题标题】:How to setup a JDI launching connector?如何设置 JDI 启动连接器?
【发布时间】:2014-03-06 10:18:28
【问题描述】:

所以我正在努力让自己融入 JDI。通过首先使用 VM 命令启动调试对象,我已经成功地将调试器应用程序挂接到我的调试对象程序中:

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

但现在我希望我的调试器应用程序启动被调试程序本身。我知道在这种情况下必须使用启动连接器。所以我尝试了这个:

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

但是,当我启动这个应用程序时,我的被调试程序没有启动。尽管上面显示的代码有一堆后续代码,但我没有得到任何异常或任何东西;像这样的东西:

    // 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...");

一切运行良好?!我确实没有例外,所有的系统输出(GO...等)。我觉得这很奇怪——显然它找到了一个主线程和一个 VMStartEvent。但我猜我的调试器是自己做这一切还是什么?恐怕我并没有真正掌握所有这些方法调用的作用。

所以我的问题是:为什么我的被调试程序没有启动?

正如您在上面看到的,我确实将“main”参数设置为:

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

我的调试器应用程序在同一个包 (p) 中。那么这应该是正确的吗?但显然我在这里做错了什么。有什么想法吗?

谢谢!

【问题讨论】:

    标签: java debugging interface connector launching


    【解决方案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;
    }
    

    【讨论】:

      【解决方案2】:

      您是否在 LaunchingConnector 中设置了类路径?

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

      【讨论】:

        猜你喜欢
        • 2015-01-24
        • 1970-01-01
        • 2021-03-04
        • 1970-01-01
        • 1970-01-01
        • 2018-12-22
        • 1970-01-01
        • 2011-02-17
        • 2023-04-05
        相关资源
        最近更新 更多