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

Dan*_*Dan 5 java debugging dynamic-loading dlopen jvmti

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

  1. 有没有办法在Java进程启动后加载代理?
  2. 有没有办法从JVMTI代码内部或从进程外部卸载Java代理(没有杀死整个Java进程)?例如,dlclose()如果我能找到动态加载模块的句柄,我可以安全地从JVMTI代码调用吗?

如果无法完成这些操作,是否有办法在加载后将数据传递给Java代理?有没有通过某些Java命令行实用程序执行此操作的常规方法?如果没有,我可以安全地创建一个线程并让它在我的代理的代码中使用标准的C或C++库调用来监听套接字吗?

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

注意:我已经看过这个但是认为可能有一些正常的方法来做这个不在JVMTI标准中.

Kon*_*che 5

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

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

  2. 我不确定,类似于1.您可以unload通过Bytecode工具运行Java 方法.如果dlclose()有效,我没有看到这样做的问题.

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