2013-06-29 2 views
4

Я пишу Java-агент для взаимодействия с JVMTI. По причинам, в которые я не попаду, мне нужно использовать JVMTI (интерфейс C внутри процесса java), а не API Java, например java.lang.instrument или JDI. Я хотел бы иметь возможность сделать пару вещей, которые, как представляется, не поддерживаются напрямую.java agent с загрузкой jvmti во время выполнения, выгрузка изнутри

  1. Есть ли способ загрузить агента после того, как процесс Java уже запущен?
  2. Есть ли способ выгрузить Java-агент (не дожидаясь уничтожения всего процесса Java) либо из кода JVMTI, либо из-за пределов процесса? Например, могу ли я безопасно позвонить dlclose() из кода JVMTI, если я могу найти дескриптор для динамически загружаемого модуля?

Если эти операции не могут быть выполнены, существует ли способ передать данные агенту Java после его загрузки? Есть ли нормальный способ сделать это через некоторую утилиту командной строки Java? Если нет, могу ли я безопасно создать поток и послушать сокет, используя стандартные вызовы библиотеки C или C++ в коде для моего агента?

Если это помогает, не беспокойтесь о поддержке Windows с ответом - я беру этот проект за расширение инструмента для отладки Unix.

Примечание: Я уже видел this, но думал, что может быть какой-то нормальный способ сделать это, что не в стандарте JVMTI.

ответ

4
  1. Вы можете только вводить (развернуть) агент либо на start time из виртуальной машины Java, передавая аргумент -agentlib:<agent-lib-name>=<options> или -agentpath:<path-to-agent>=<options>.

    Другой способ - через Java. Это сильно зависит от JVM, по этой причине оно выходит за пределы спецификации JVMTI. Например, если существует класс VirtualMachine с помощью метода loadAgentPath(agentPath, options). Если вы хотите выполнить это с помощью собственного кода JVMTI, вам нужно будет использовать инструментарий Bytecode.

  2. Я не уверен, аналогично 1. вы можете запустить метод Java unload с помощью инструментария Bytecode. Если работает dlclose(), я не вижу проблемы с этим.

Как вы видите, вы можете передавать данные агенту Java с помощью опций. Кроме того, если вы хотите передавать данные непрерывно между обоими экземплярами, вы можете открыть два сокета и написать/прочитать между ними. Я использовал Protobuf