LINUX.ORG.RU

Скомпилировать JVM с поддержкой JVM TI

 


0

1

Клонировал репу OpenJDK, скомпилировал по инструкции. Но в JVM, который у меня получился, отсутствует поддержка JVM TI. Когда я пытаюсь подключить своего агента, то получаю ошибку (JVMTI_ERROR_NOT_AVAILABLE = 98).

//...
jvmtiError e;
jvmtiCapabilities capa;
capa.can_generate_method_entry_events = 1;
capa.can_generate_method_exit_events = 1;
e = env->AddCapabilities(&capa);
//...

Такой код нормально работает на JVM из пакета, но не работает на моей JVM.



Последнее исправление: pdip28 (всего исправлений: 1)

По какой инструкции скомпилировал? Видать неправильно скомпилировал. Какая версия/бранч OpenJDK?

stevejobs ★★★★☆
()
Ответ на: комментарий от stevejobs

Проблема решилась. Оказывается, нельзя заполнять jvmtiCapabilities таким образом, как это делал я. Если добавить

env->GetCapabilities(&capa);
перед
capa.can_generate_method_entry_events = 1;
capa.can_generate_method_exit_events = 1;
e = env->AddCapabilities(&capa);
то будет все нормально работать. Видимо, я где-то ошибся, когда проверял свой код.

pdip28
() автор топика
1 октября 2015 г.

Возникла еще одна проблема с поддержкой JVM TI на самостоятельно скомпилированной JVM. Заключается в том, что я не могу получить FramePop событие. Больше никаких проблем не было обнаружено. При этом, на JVM из пакета (OpenJDK) все работает хорошо.

Собираю JDK следующим образом:

hg clone http://hg.openjdk.java.net/lambda/lambda
cd lambda
./get_source.sh
sh configure
make
sudo make install

Код OpenJDK я не изменяю.

Как я устанавливаю уведомление:

jvmtiError jvmti_error;
jint jni_error;

JavaVM *jvm;
jni_error = env->GetJavaVM(&jvm);
if (jni_error != JNI_OK) {
	LOG(ERROR) << "cannot get jvm";
	return JNI_FALSE;
}

jvmtiEnv *jvmti;
jni_error = jvm->GetEnv(reinterpret_cast<void **>(&jvmti), JVMTI_VERSION_1_2);
if (jni_error != JNI_OK) {
	LOG(ERROR) << "cannot get jvmti";
	return JNI_FALSE;
}

jvmtiCapabilities caps;

memset(&caps, 0, sizeof(caps));
caps.can_generate_frame_pop_events = 1;
jvmti_error = jvmti->AddCapabilities(&caps);
if (jvmti_error != JVMTI_ERROR_NONE) {
	LOG(ERROR) << "cannot set capability";
}

jvmtiEventCallbacks callbacks;
memset(&callbacks, 0, sizeof(jvmtiEventCallbacks));
callbacks.FramePop = frame_pop;
jvmti_error = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
if (jvmti_error != JVMTI_ERROR_NONE) {
	LOG(ERROR) << "cannot set event callback";
}

jvmti_error = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_FRAME_POP, NULL);
if (jvmti_error != JVMTI_ERROR_NONE) {
	LOG(ERROR) << "cannot set event notification mode";
}

jvmti_error = jvmti->NotifyFramePop(NULL, 1);
if (jvmti_error != JVMTI_ERROR_NONE) {
	LOG(ERROR) << "cannot set notification";
}

pdip28
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.