首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JVMTI代理崩溃

JVMTI代理崩溃
EN

Stack Overflow用户
提问于 2011-09-15 01:57:42
回答 1查看 3.3K关注 0票数 2

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

FATAL ERROR in native method: Using JNIEnv in the wrong thread at Proxy.monitor_enter_(Native Method) at Proxy.monitor_enter(Proxy.java:30) at ex1.LifeThreads.setNeighborThreadChange(LifeThreads.java:36) at ex1.LifeThreads.neighbor(LifeThreads.java:425) at ex1.LifeThreads.standardItr(LifeThreads.java:321) at ex1.LifeThreads.run(LifeThreads.java:462)

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

在代码中,我执行了与各种JDK示例(通过带有本机方法的代理java类实现的heapViewer、heapTracker等)相同类型的插装。在每条monitorenter指令之后调用Proxy.monitor_enter_本机方法。

这是monitor_enter_的代码

代码语言:javascript
复制
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 enter/exit的范围锁,thread_t只是一个包装了一些std::vector的结构,当thread->lock( lock(global_ref))被调用时,类lock (它本身只包装jobject全局引用global_ref)的实例就存储在这个结构中。

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

代码语言:javascript
复制
    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;
}
EN

回答 1

Stack Overflow用户

发布于 2012-04-10 15:44:53

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7420806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档