如何设置JDI启动连接器

如何设置JDI启动连接器

本文介绍了如何设置JDI启动连接器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I'm trying to work myself into JDI. I was already successful hooking my debugger application into my debugee program by first starting the debuggee with VM commands:

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

然后启动我的调试器以建立连接使用附加连接器:

and then launching my debugger which establishes a connection by the use of an attaching connector:

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

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

But now I want my debugger application to start the debuggee program itself. I understand one must use the launching connector in that case. So I tried this:

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

但是,当我启动此应用程序时,我的debugee程序无法启动。我没有例外或任何事情,尽管上面的代码有一堆后续代码;类似于:

However, when I start this application, my debugee program does not get launched. I get no exceptions or anything, despite of having a bunch of follow-up code to the code showed above; 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。但是我猜我的调试器是自己做的还是什么?我担心我没有真正掌握所有这些方法调用的功能。

It all runs just fine?! I do get no exceptions and all the sysouts (GO... etc). I find that quite strange -- obviously it finds a main thread and a VMStartEvent. But I guess my debugger is doing this all to itself or something? I'm afraid I didn't really grasp what all these method calls do.

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

如上所示,我确实将主参数设置为:

As you can see above I did setup the "main" argument to:

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

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

My debugger application is in that same package (p). So that should be correct? But obviously I'm doing something wrong here. Any ideas?

谢谢!

推荐答案

这可能是因为你不处理子进程stdin / stdout流。我有一个我的JDI脚本项目中的实用程序类来处理这个问题;相关代码是:

It's probably because you aren't handling the subprocess stdin/stdout streams. I've got a VMLauncher utility class in my JDI scripting project that handles this; the relevant code is:

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

这篇关于如何设置JDI启动连接器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 21:25