如何调试使用JVMTI代理设置断点的Java应用程序(无法获得必要的JVMTI功能)

时间:2016-06-05 14:29:13

标签: java debugging profiling jvmti yourkit

我想调试使用我编写的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代理,但仍允许您以调试模式运行应用程序(好吧,也许他们只是没有使用导致这些冲突的功能)。

2 个答案:

答案 0 :(得分:2)

TL; DR

调试JVM代理使用本机代码调试器,例如GDB。

稍微详细一点

Java应用程序中存在两种代码 - Java代码(应用程序本身和基于java.lang.instrument的代理程序)和本机代码(Java类的本机方法,JVMTI代理程序和VM本身)。要调试前者,您需要使用Java调试器(使用JDWP)。要调试后者,您需要像使用C / C ++程序一样使用常规本机代码调试器。如果要同时调试Java和本机代码,则需要使用两个调试器。

关于JVMTI代理,JDWP以及需要什么

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的支持,并允许调试器连接到它(我认为这本身就是一个项目)