我想调试使用我编写的jvmti代理的java应用程序。这似乎只有在jvmti代理没有尝试启用" can_generate_breakpoint_events"能力。
尝试启用断点功能并在调试模式下启动应用程序会导致以下错误:
ERROR: JVMTI: 98(Unknown): Unable to get necessary JVMTI capabilities. [..\src\agent.cpp:437]
有没有办法调试使用jvmti代理设置断点的应用程序?
我检查Java JVMTI doesn't work alongside -Xdebug -Xrunjdwp但是接受的答案似乎不正确,因为它似乎也依赖于启用的功能。
我知道分析器(如YourKit等)也在使用jvmti代理,但仍允许您以调试模式运行应用程序(好吧,也许他们只是没有使用导致这些冲突的功能)。
答案 0 :(得分:2)
调试JVM代理使用本机代码调试器,例如GDB。
Java应用程序中存在两种代码 - Java代码(应用程序本身和基于java.lang.instrument的代理程序)和本机代码(Java类的本机方法,JVMTI代理程序和VM本身)。要调试前者,您需要使用Java调试器(使用JDWP)。要调试后者,您需要像使用C / C ++程序一样使用常规本机代码调试器。如果要同时调试Java和本机代码,则需要使用两个调试器。
JVM可以在多个代理一起运行的情况下启动,每个代理都有自己的JVMTI环境(功能,事件监听器等)。但是,如果多个代理(或单个代理的多个实例)使用相同的资源,例如相同的全局变量,然后它们可以相互影响(这是JDK的JDWP代理的情况 - 这就是为什么你最多只能有一个-agentlib:jdwp
)。
JDWP是Java调试器的协议。 JDWP代理是随JDK一起提供的JVMTI代理,它支持JVM中的JDWP协议。它是一个普通的JVMTI代理,可以与其他代理一起启动。
答案 1 :(得分:0)
根据我目前的理解,答案其实就是以下几点。来自JVMTI doc:
每个JVM TI实现的潜在可用功能都不同。根据实施情况,能力:
- ...
- 一次只能拥有一个环境
- ...
设置断点和观察点似乎只能由一个环境所拥有的能力类型。
所以问题是我的代理尝试声明can_generate_breakpoint功能,但调试器代理也需要它们。因此,有两个代理请求这些功能导致上述错误。
对我而言,这意味着您无法调试以需要能够设置断点的JVM TI代理启动的Java应用程序。
我能想到的唯一理论解决方案是我的JVM TI代理还实现了对JDWP的支持,并允许调试器连接到它(我认为这本身就是一个项目)