在运行时加载jvmti的java代理,从内部卸载

时间:2013-06-29 05:48:38

标签: java debugging dlopen dynamic-loading jvmti

我正在编写一个Java代理来与JVMTI进行交互。由于我不会涉及的原因,我需要使用JVMTI(java进程中的C接口)而不是像java.lang.instrument或JDI这样的Java API。我希望能够做一些似乎不能直接支持的事情。

  1. 有没有办法在Java进程启动后加载代理?
  2. 有没有办法从JVMTI代码内部或从进程外部卸载Java代理(没有杀死整个Java进程)?例如,如果我能找到动态加载模块的句柄,我可以安全地从JVMTI代码中调用dlclose()吗?
  3. 如果无法完成这些操作,有没有办法在加载后将数据传递给Java代理?有没有通过某些Java命令行实用程序执行此操作的常规方法?如果没有,我可以安全地创建一个线程并让它在我的代理的代码中使用标准的C或C ++库调用来监听套接字吗?

    如果它有帮助,不要担心支持Windows的答案 - 我正在进行这个项目来扩展一个只有Unix的调试工具。

    注意:我已经看过this,但认为可能有一些正常的方法可以做到这一点,而不是JVMTI标准。

1 个答案:

答案 0 :(得分:5)

  1. 您只能通过传递参数-agentlib:<agent-lib-name>=<options>-agentpath:<path-to-agent>=<options>在JVM的start time注入(部署)代理。

    另一种方式是通过Java本身。这在很大程度上取决于JVM,因此它超出了JVMTI规范范围。例如,如果通过方法VirtualMachine存在loadAgentPath(agentPath, options)类。如果要在本机JVMTI代码中执行此操作,则需要执行Bytecode检测。

  2. 我不确定,类似于1.你可以通过Bytecode工具运行Java unload方法。如果dlclose()有效,我认为没有问题。

  3. 如您所见,您可以使用选项将数据传递给Java代理。或者,如果要在两个实例之间连续传递数据,可以打开两个套接字并在它们之间进行写入/读取。我使用了Protobuf