2014-11-21 3 views
1

У нас есть приложение, где большая часть моего кода написана на C++. Мы используем интерфейс JNI. Обратные вызовы событий передаются в java с использованием этого интерфейса JNI. Для каждого обратного вызова события мы получаем JNIEnv, а затем вызываем AttachCurrentThread для этого env. Ниже приведен фрагмент кода, который делает это:родной сбой при ART при вызове 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, который в свою очередь получает окр для текущего потока и прикрепляет текущий поток. Этот поток отключается, когда этот объект CJniUtil является деструктором. На Dalvic этот фрагмент кода работает отлично, но на ART (Android Run Time) он рушится (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.

+0

Смотрите _ [Будет ли мой Android App по-прежнему работать с АРТ вместо Dalvik?] (https://software.intel.com/en-us/blogs/2014/ 07/23/will-my-android-app-still-run-with-art-вместо-dalvik) _: ** 11 ** Посмотрите размер pthread (pthreat_attr_setstack() и pthreat_attr_setstacksize()) как вызовы, включая AttachCurrentThread () выдает ошибку. –

ответ

0

У Dalvik были отдельные стеки для собственного и Java-кода с размером стека Java по умолчанию 32 КБ и размером ядра по умолчанию 1 МБ. У ART есть единый стек для лучшей локальности. Обычно размер стека ART Thread должен быть примерно таким же, как для Dalvik. Однако, если вы явно устанавливаете размеры стека, вам может потребоваться вернуться к этим значениям для приложений, работающих в АРТ.

В Java просматривайте вызовы конструктора Thread, которые задают явный размер стека. Например, вам потребуется увеличить размер, если StackOverflowError. В C/C++ рассмотрите использование pthread_attr_setstack() и pthread_attr_setstacksize() для потоков, которые также запускают Java-код через JNI. Вот пример ошибки, зарегистрированной, когда приложение пытается вызвать JNI AttachCurrentThread(), когда размер pthread слишком мал: F/art: art/runtime/thread.cc: 435] Попытка присоединить поток с помощью слишком -малые стек (16384 байт)

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

Смежные вопросы