Java agent with jvmti loading at runtime, unloading from inside

I am writing a Java agent to interact with the JVMTI. For reasons that I wonโ€™t fall into, I need to use the JVMTI (C interface inside the java process) rather than the Java API like java.lang.instrument or JDI. I would like to be able to do a couple of things that do not seem to be supported directly.

  • Is there a way to load the agent after the Java process is already running?
  • Is there a way to unload a Java agent (without waiting for the entire Java process to be killed), either from JVMTI code or from outside the process? For example, is it safe to call dlclose() from JVMTI code if I can find a handle to a dynamically loaded module?

If these operations cannot be performed, is there a way to pass data to the Java agent after it is downloaded? Is there a normal way to do this through some Java command line utility? If not, can I safely create a stream and listen on a socket using standard C or C ++ library calls in the code for my agent?

If this helps, donโ€™t worry about Windows support with the answer - Iโ€™m taking this project to expand the Unix debugging tool.

Note: I already saw this one , but thought there might be some normal way to do this, which is not in the JVMTI standard.

+4
source share
1 answer
  • You can only enter (expand) the agent either at the start of the JVM by passing the argument -agentlib:<agent-lib-name>=<options> or -agentpath:<path-to-agent>=<options> .

    Another way is Java itself. It is highly dependent on the JVM, for this reason it goes beyond the JVMTI specification. For example, if the VirtualMachine class VirtualMachine using the loadAgentPath(agentPath, options) method. If you want to accomplish this using the built-in JVMTI code, you will need to use the Bytecode toolkit.

  • I'm not sure, similar to 1. you can run the Java unload method using the Bytecode toolkit. If dlclose() works, I don't see a problem with this.

As you can see, you can pass data to the Java agent using options. In addition, if you want to transfer data continuously between both instances, you can open two sockets and write / read between them. I used Protobuf

+4
source

Source: https://habr.com/ru/post/1488816/


All Articles