Android вызывает JVMTI со стороны Java через JNI не удалось, указатель равен NULL - PullRequest
1 голос
/ 15 октября 2019

Я написал агент для использования 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, Не удается получить доступ к агенту, я не знаю почему.

...