在 Java 进程中,我想访问同一进程的 JDI(Java 调试接口)。
我做出以下假设:
- 该进程正在调试器中执行(在 Intelli/J 中)
- 我使用 Oracle JVM 8
- 我运行 Linux(不需要可移植性)
也就是说,我想做类似的事情:
import com.sun.jdi.*
import com.sun.jdi.connect.*
VirtualMachine vm = new SelfConnector().attach()
(当然,除了没有这样的对象。)
如何连接到我自己的虚拟机?
我为什么要那个?
我希望编写一个函数,通过它的唯一 IDfindObj
找到一个对象。例如,如果在 Intelli/J 调试器中我看到一个变量“ ”,那么我希望能够添加一个查找并返回对象的监视表达式“”。这样,即使在更改变量或离开当前堆栈帧之后,我也将能够看到对象 #1234 。x = {Something@1234}
findObj(1234)
x
我相信一旦我可以访问当前进程的 JDI,我就可以实现这个功能。
[编辑:它没有回答问题,但它解决了我的用例:在 Intellij/J 中,您可以“标记”对象,并在监视表达式中使用这些标记。]
我尝试了什么?
在调试会话中启动 Java 进程时,我尝试使用 Intelli/J 在参数中提供的主机名和端口通过 SocketAttach AttachingConnector连接到进程本身。-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:39469,suspend=y,server=n
(大致遵循此处描述的方法。)我得到:
Exception in thread "main" java.net.ConnectException: Connection refused
可能是因为 Intelli/J 已经连接并且无法连接到该端口两次?[编辑:Intellij/J 使用参数启动 jwdp 代理,server=n
这意味着该进程将进行连接。因此连接被拒绝。但进一步的实验表明,即使一个使用server=y
,最多只能接受一个连接。]
另一种方法是使用 ProcessAttach AttachingConnector。在这种情况下,我得到:
Exception in thread "main" java.io.IOException: Not a debuggee, or not listening for debugger to attach