0

我正在开发我的自定义调试器作为 Eclipse 插件。为此,我正在使用 JPDA API。我想检索一些对象引用变量的值。因此,我尝试通过调用 toString() 方法来使用ObjectReference.invokeMethod 。我的代码如下:

if(thread.isSuspended()){
    Method method = retriveToStringMethod(...);
    Value messageValue = objValue.invokeMethod(thread, method, new ArrayList<Value>(), ObjectReference.INVOKE_SINGLE_THREADED); 
    stringValue = messageValue.toString();

}

但是,它有时不起作用。例如,给定以下代码:

1. public static void main(String[] args) {
2.  InsertIntervalBug6 insert = new InsertIntervalBug6();
3.  
4.  Interval i1 = new Interval(1, 2);
5.  Interval i2 = new Interval(3, 4);
6.  
7. }

它在第 4 行运行良好,我可以通过调用插入变量的 toString() 方法成功获得结果。但是,在第 5 行时,会报告 TimeOutException。但是,我已经设置了 10s 启动 JVM 时的超时选项,因此我认为这样的时间足够长,可以检索到 toString() 方法调用的结果。跟踪堆栈如下。你对这个问题有任何想法吗?谢谢!

org.eclipse.jdi.TimeoutException:在 org.eclipse.jdi.internal.connect.PacketReceiveManager 的 org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:186) 处等待数据包 586 时发生超时。 getReply(PacketReceiveManager.java:197) at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:191) at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:226) at org.eclipse .jdi.internal.ObjectReferenceImpl.invokeMethod(ObjectReferenceImpl.java:428) 在 microbat.codeanalysis.runtime.variable.VariableValueExtractor.setMessageValue(VariableValueExtractor.java:518)

4

1 回答 1

0

我自己解决了这个问题。我在这个答案中分享解决方案如下:

TimeoutException 是由死锁引起的。当我访问 toString() 方法时,它会触发对 JVM 的步骤请求。但是,我的程序正在侦听从调试程序发送的任何步进请求,以便它能够捕获步进事件并暂停程序以检查变量值。因此,以编程方式调用 toString() 方法会挂起程序本身,invokeMethod() 会等待挂起的程序,直到时间输出。

解决方案是禁用设置步骤请求。之后,期限锁定问题就消失了。

于 2016-05-21T02:41:03.213 回答