调用attachCurrentThread时在ART下的本机崩溃

时间:2014-11-21 06:11:58

标签: android java-native-interface native

我们有一个应用程序,其中大部分代码都是用C ++编写的。我们正在使用JNI接口。使用此JNI接口将事件回调传递给java。对于每个事件回调,我们得到JNIEnv,然后为该环境调用AttachCurrentThread。以下是执行此操作的代码:

CJniEnvUtil::CJniEnvUtil(JavaVM *pvm)
: m_fNeedDetach(false)
, mJavaVM(pvm)
, m_pEnv(NULL)
{
    switch (mJavaVM->GetEnv((void**)&m_pEnv, JNI_VERSION_1_6)) { 
        case JNI_OK: break; 
        case JNI_EDETACHED: 
            if (mJavaVM->AttachCurrentThread(&m_pEnv, NULL) != 0) { 
                break;
            } 
            m_fNeedDetach = true;
           break; 
        case JNI_EVERSION: 
            break;
    }
}

CJniEnvUtil::~CJniEnvUtil()
{
    if (m_fNeedDetach && m_pEnv) 
        mJavaVM->DetachCurrentThread(); 
}

所以我的想法是,对于每个事件回调,我们创建这个CJniEnvUtil的实例,然后获取当前线程的env并附加当前线程。当此CJniUtil对象是析构函数时,此分离的线程。 在Dalvic上,这段代码完美无缺,但是在ART(Android运行时)它崩溃了(Inface一个理智失败)。 以下是来自logcat的完整堆栈跟踪。

A/art﹕ art/runtime/thread.cc:468] Check failed: &stack_variable > reinterpret_cast<void*>          (stack_end_) (&stack_variable=0x4cd061b0, reinterpret_cast<void*>(stack_end_)=0x50014000)
I/AudioFlinger﹕ BUFFER TIMEOUT: remove(4098) from active list on thread 0xb5e81008
A/art﹕ art/runtime/runtime.cc:203] Runtime aborting...
A/art﹕ art/runtime/runtime.cc:203] Aborting thread:
A/art﹕ art/runtime/runtime.cc:203] "<native thread without managed peer>" prio=5 tid=27 Runnable (still starting up)
A/art﹕ art/runtime/runtime.cc:203]   | group="" sCount=0 dsCount=0 obj=0x00000000 self=0x497e4830
A/art﹕ art/runtime/runtime.cc:203]   | sysTid=10564 nice=0 cgrp=apps sched=0/0 handle=0x4f2e9cd0
A/art﹕ art/runtime/runtime.cc:203]   | state=R schedstat=( 3985475838 2078977182 16206 ) utm=335 stm=63 core=0 HZ=100
A/art﹕ art/runtime/runtime.cc:203]   | stack=0x50010000-0x50014000 stackSize=1016KB
A/art﹕ art/runtime/runtime.cc:203]   native: art::Thread::DumpStack(std::ostream&) const+87         
A/art﹕ art/runtime/runtime.cc:203]   native: art::Runtime::Abort()+79 [0x41634974] (libart.so)
A/art﹕ art/runtime/runtime.cc:203]   native: art::LogMessage::~LogMessage()+505 [0x414e193a] (libart.so)
A/art﹕ art/runtime/runtime.cc:203]   native: art::Thread::InitStackHwm()+849 [0x4163da9a] (libart.so)
A/art﹕ art/runtime/runtime.cc:203]   native: art::Thread::Init(art::ThreadList*,      art::JavaVMExt*)+499 [0x4163dd78] (libart.so)
A/art﹕ art/runtime/runtime.cc:203]   native: art::Thread::Attach(char const*, bool, _jobject*,  bool)+103 [0x41645250] (libart.so)
A/art﹕ art/runtime/runtime.cc:203]   native: art::Runtime::AttachCurrentThread(char const*,  bool, _jobject*, bool)+15 [0x41632b38] (libart.so)

如第一行所示,完整性检查失败。

如果有人可以对此提出建议,我将非常感激。我必须在Android 5.0上运行应用程序,它将ART作为默认运行时。

1 个答案:

答案 0 :(得分:0)

Dalvik拥有独立的本机和Java代码堆栈,默认Java堆栈大小为32KB,默认本机堆栈大小为1MB。 ART具有统一的堆栈以获得更好的局部性。通常,ART Thread堆栈大小应与Dalvik大致相同。但是,如果您明确设置堆栈大小,则可能需要重新访问在ART中运行的应用程序的这些值。

在Java中,查看对Thread构造函数的调用,该构造函数指定显式堆栈大小。例如,如果发生StackOverflowError,则需要增加大小。 在C / C ++中,查看对也通过JNI运行Java代码的线程使用pthread_attr_setstack()和pthread_attr_setstacksize()。以下是当pthread大小太小时应用程序尝试调用JNI AttachCurrentThread()时记录的错误示例: F / art:art / runtime / thread.cc:435]     尝试附加一个堆栈太小(16384字节)的线程

https://developer.android.com/guide/practices/verifying-apps-art.html#Stack_Size