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

标签 java debugging dlopen dynamic-loading jvmti

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

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

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

如果有帮助,请不要担心您的回答是否支持 Windows - 我正在进行此项目以扩展仅适用于 Unix 的调试工具。

注意:我已经看到了this但认为可能有一些不在 JVMTI 标准中的常规方法。

最佳答案

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

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

  2. 我不确定,类似于 1。您可以运行 Java unload通过字节码检测的方法。如果dlclose()可行,我认为这样做没有问题。

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

关于带有 jvmti 的 java 代理在运行时加载,从内部卸载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17377130/

相关文章:

Android JNI 使用 dlopen() 代替 system.loadlib

java - 避免将 Spring Framework 特定服务显示为 Swagger 界面的一部分

xcode - xcode 中的任何即时 Pane ,如 Visual Studio 或 VBA?

c++ - 你曾经让调试器崩溃过吗?

java - Weblogic集群环境下如何设置远程调试?

c - 如何让共享库中的符号覆盖现有符号?

java - 在 thymeleaf 中编写 Java 代码

java.net.SocketException : Socket is closed while socket is still open

java - 空的 editText 字段在所有字段上显示错误 [Android]

c++ - 使用 dlopen 时,我应该链接到我打开的库吗?