JDI VMDisconnectedException

时间:2014-10-28 13:36:49

标签: java jdi vmdisconnectedexception

我正在使用JDI为Java应用程序编写调试器。

我使用以下方式运行debugee流程:

'/usr/lib/jvm/jdk-8-oracle-x64/bin/java -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y -cp (...) program.entrypoint.Test'

这是一个非常简单的程序。它只是实例化一个Test对象,并在for循环中将foo字段设置为0..10。

现在我从这个网站下载的调试程序: link

public class FieldMonitor {

    public static void main(String[] args) throws IOException, InterruptedException {
        // connect
        VirtualMachine vm = new VMProvider().connect(8000);

        vm.resume();

        EventQueue eventQueue = vm.eventQueue();
        while (true) {
            EventSet eventSet = eventQueue.remove();
            for (Event event : eventSet) {
                try {
                    System.out.println(event);

                    if (event instanceof VMDeathEvent || event instanceof VMDisconnectEvent) {
                        return;
                    }
                    else if(...)
                }
                catch(VMDisconnectedException e) {
                    e.printStackTrace();
                }
            }
            eventSet.resume();
        }
    }
}

通常情况下,我会听更多事件,例如点击断点等,但即使是正常的程序执行也应至少打印出来:

VMStartEvent in thread main
VMDeathEvent

然而,当我尝试打印事件时,我会随机抛出一个异常VMDisconnectedException。然后我会得到:

com.sun.jdi.VMDisconnectedException
    at com.sun.tools.jdi.TargetVM.waitForReply(TargetVM.java:304)
    at com.sun.tools.jdi.VirtualMachineImpl.waitForTargetReply(VirtualMachineImpl.java:1036)
    at com.sun.tools.jdi.PacketStream.waitForReply(PacketStream.java:69)
    at com.sun.tools.jdi.JDWP$ThreadReference$Name.waitForReply(JDWP.java:4931)
    at com.sun.tools.jdi.JDWP$ThreadReference$Name.process(JDWP.java:4912)
    at com.sun.tools.jdi.ThreadReferenceImpl.name(ThreadReferenceImpl.java:168)
    at com.sun.tools.jdi.EventSetImpl$ThreadedEventImpl.toString(EventSetImpl.java:184)
    at java.lang.String.valueOf(String.java:2981)
    at java.io.PrintStream.println(PrintStream.java:821)
    at virtualmachine.FieldMonitor.main(FieldMonitor.java:33)
VMDeathEvent

我的VMStartEvent(或任何其他如果我收听更多事件)现在存在异常。当我在catch子句中放置一个断点时,我得到:

com.sun.jdi.VMDisconnectedException: connection is closed

在此异常之后,我仍然从集合中获取VMDeathEvent。 现在,我不知道为什么会随机发生这种情况,以及为什么会发生这种情况,因为我的debugee进程是以暂停的方式启动的,而我只是在将自己作为调试器后才恢复它。

2 个答案:

答案 0 :(得分:0)

首先,需要更多关于你正在做什么事件的信息。这是我类似程序的输出:

VMStartEvent in thread main
VMDeathEvent
VMDisconnectEvent

但是,我没有声明:

vm.resume();

如果我加入它,我会得到同样的例外。

Exception in thread "main" com.sun.jdi.VMDisconnectedException: connection is closed
    at com.sun.tools.jdi.TargetVM.send(TargetVM.java:274)
    at com.sun.tools.jdi.VirtualMachineImpl.sendToTarget(VirtualMachineImpl.java:1011)
    at com.sun.tools.jdi.PacketStream.send(PacketStream.java:41)
    at com.sun.tools.jdi.JDWP$ThreadReference$Name.enqueueCommand(JDWP.java:4928)
    at com.sun.tools.jdi.JDWP$ThreadReference$Name.process(JDWP.java:4914)
    at com.sun.tools.jdi.ThreadReferenceImpl.name(ThreadReferenceImpl.java:77)
    at com.sun.tools.jdi.EventSetImpl$ThreadedEventImpl.toString(EventSetImpl.java:168)
    at java.lang.String.valueOf(String.java:2826)
    at java.io.PrintStream.println(PrintStream.java:771)

所以,我想这与导致问题的vm.resume()函数调用有关。 希望,这有帮助。

答案 1 :(得分:0)

异常由 event.toString 发生在 System.out.println(event) 内引发。如果事件是 ThreadedEventImpl 的实例,则可能发生这种情况:

public String toString() {
    return eventName() + " in thread " + thread.name();
}

因为 thread.name() 向 VM 发送命令并等待回复,但 VM 可能已经断开连接。