gpt4 book ai didi

java - JVMTI 代理崩溃

转载 作者:行者123 更新时间:2023-11-29 09:19:20 28 4
gpt4 key购买 nike

我正致力于将橡皮擦数据争用检测算法作为 JVMTI 代理来实现。当我尝试运行一些示例输入来测试我的代码时,JVM 崩溃,转储如下所示(也可能显示相同错误的其他堆栈跟踪):

native 方法中的 fatal error :在错误的线程中使用 JNIEnv
在 Proxy.monitor_enter_( native 方法)
在 Proxy.monitor_enter(Proxy.java:30)
在 ex1.LifeThreads.setNeighborThreadChange(LifeThreads.java:36)
在 ex1.LifeThreads.neighbor(LifeThreads.java:425)
在 ex1.LifeThreads.standardItr(LifeThreads.java:321)
在 ex1.LifeThreads.run(LifeThreads.java:462)

(这种事后跟踪可以通过 Sun JVM 的 -Xcheck:jni 选项获得)

在代码中,我执行了与各种 JDK 示例中所示的相同类型的检测(heapViewer、heapTracker 等,通过一些具有 native 方法的代理 java 类)。 Proxy.monitor_enter_ native 方法在每个 monitorenter 指令后调用。

这是 monitor_enter_ 的代码:

void native_monitor_exit(JNIEnv *jni, jclass klass, jthread thread_id, jobject obj)
{
scoped_lock( agent::instance()->jvmti(), agent::instance()->monitor_ );
if( agent::instance()->death_active_)
return;

std::string name = agent::instance()->thread_name( thread_id );
thread_t* thread = get_thread( thread_id );
if( thread == 0 )
return;
jobject global_ref = agent::instance()->jni()->NewGlobalRef( obj );
if( global_ref == 0 )
fatal_error("Out of memory while trying to create new global ref.");

logger::instance()->level(1) << "MONITOR ENTER"
<< "\n\t" << "jthread name= " << name
<< "\n\t" << "thread_t= " << thread << " " << *thread
<< "\n\t" << "monitor gl= " << global_ref
<< std::endl;

thread->lock( lock(global_ref) );
}

,其中 scoped_lock 基本上是 JVMTI Raw Monitor 进入/退出的作用域锁,thread_t 只是一个包装一些 std::vector 的结构,其中类 lock 的实例(它本身只是包装 jobject 全局引用 global_ref) 被存储,当 thread->lock( lock(global_ref)) 被调用时。

JVMTI 环境。在代理单例中全局缓存,而线程本地的 JNI env 每次在使用前都会重新加载(效率不高,但现在我不关心),如下所示:

    JNIEnv* jni()
{
jint res;
JNIEnv* env = 0;
res = jvm()->GetEnv( (void**)&env, JNI_VERSION_1_2 );
if( res == JNI_EDETACHED )
{
res = jvm()->AttachCurrentThread( (void **)&env, 0 );
if( res != JNI_OK || env == 0 )
fatal_error( "ERROR: Unable to create JNIEnv by attach, error=%d\n", res );
}
else if( res != JNI_OK || env == 0 )
fatal_error( "ERROR: Unable to create JNIEnv, error=%d\n", res );
}
return env;
}

最佳答案

您应该使用传递给您的 native_monitor_exit 方法的 jni 参数,而不是在您的 jni() 方法中查找它,它是从 Java 调用方法时应该使用的 jni 环境。

关于java - JVMTI 代理崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7420806/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com