Я написал агент для использования JVMTI на android 9. В коде, подобном этому, я создаю объект AgentFunction для мониторинга виртуальной машины. Это работает нормально.
AgentFunction * agent = 0;
JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM *vm, char *options, void *reserved) {
agent = new AgentFunction();
agent->Init(vm);
agent->ParseOptions(options);
agent->AddCapability();
agent->ShowCapabilities();
agent->RegisterEvent();
return JNI_OK;
}
Затем я хочу экспортировать некоторый интерфейс в Java, чем пользователь может напрямую вызвать функцию JVMTI.
private native boolean applyChangeNative(List<ClassInfo> classes);
Слияние JNI в agent.so
extern "C"
JNIEXPORT jboolean JNICALL Java_com_cc_jvmtiagent_JVMTIFunction_applyChangeNative
(JNIEnv *jniEnv, jobject, jlong jvmti, jobject classInfo) {
...
jvmtiClassDefinition *def = new jvmtiClassDefinition[total_classes];
agent->RedefineClasses(total_classes, def);
}
Но при вызове собственного метода applyChangeNative из JAVA сбой agent->RedefineClasses
, вызванный agent
, является нулевым. После теста я обнаружил, что не могу получить доступ к объекту создания в JVMTI из JNI.
Я прочитал исходный код JDK, обнаружил, что у него есть InvocationAdapter.cc. Когда Agent_OnAttach создает JPLISAgent, затемсоздайте java.lang.instrument.Instrumentation и сохраните в нем JPLISAgent. Каждая функция из Java получит точку JPLISAgent.
Но я хочу знать, почему доступ к объекту JVMTI равен NULL напрямую из JNI?
Решено:
Если вы хотите вызвать метод агента через JNI,Вы должны использовать System.Load (agentPath) вместо System.LoadLibrary (libName). Он должен использовать тот же файл.
Он работает на Android 9 и 10, но на Android 8.x, Не удается получить доступ к агенту, я не знаю почему.