3

Jumping straight to the topic, Android L introduces a ART as default runtime. I have a Sample Application, basically a document viewer. Most of the document viewing code including back buttons, Search,etc are written in C and the Android App uses JNI interface. I updated my code to make it build for Android L and it seems to open the document just fine. However, when pressing back button and closing the document, the Application seem to crash and the following backtrace is seen:

I/DEBUG   ( 1390): Abort message: 'art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: JNI CallIntMethodV called with pending exception 'java.lang.StackOverflowError' thrown in unknown throw location'
I/DEBUG   ( 1390): backtrace:
I/DEBUG   ( 1390):     #00 pc 000390d0  /system/lib/libc.so (tgkill+12)
I/DEBUG   ( 1390):     #01 pc 0001636d  /system/lib/libc.so (pthread_kill+64)
I/DEBUG   ( 1390):     #02 pc 00016e41  /system/lib/libc.so (raise+10)
I/DEBUG   ( 1390):     #03 pc 00013cdd  /system/lib/libc.so (__libc_android_abort+36)
I/DEBUG   ( 1390):     #04 pc 000125ac  /system/lib/libc.so (abort+4)
I/DEBUG   ( 1390):     #05 pc 00230fe9  /system/lib/libart.so (art::Runtime::Abort()+188)
I/DEBUG   ( 1390):     #06 pc 000b9571  /system/lib/libart.so     (art::LogMessage::~LogMessage()+1360)
I/DEBUG   ( 1390):     #07 pc 000c28cd  /system/lib/libart.so (art::JniAbort(char const*, char const*)+1124)
I/DEBUG   ( 1390):     #08 pc 000c2e11  /system/lib/libart.so (art::JniAbortF(char const*, char const*, ...)+68)
I/DEBUG   ( 1390):     #09 pc 000c65e9  /system/lib/libart.so (art::ScopedCheck::ScopedCheck(_JNIEnv*, int, char const*)+1952)
I/DEBUG   ( 1390):     #10 pc 000cc8eb  /system/lib/libart.so (art::CheckJNI::CallIntMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+42)

Upon pressing back button, when file descriptor is supposed to close, CallIntMethodV is invoked, which ultimately fails in check JNI. Same code seems to work just fine on dalvik. I had to add the following flags to make JNI code compile fine for Android L preview:

-Wno-switch -Wno-sizeof-pointer-memaccess
LOCAL_DISABLE_FORMAT_STRING_CHECKS := true

The key point is why it starts failing now on art, but not on dalvik. Any specific changes in CallIntMethodV causing the problem or compiler strictness is causing such error to be raised? Any pointers. I will be happy to provide additional details if required.

UPDATE: I temporarily disabled the call to File Close function that the native code calls into JNI and I do not seem to see any crash now.

learn_develop
  • 1,735
  • 4
  • 15
  • 33
  • did you see my answer in the comments above? ) I will leave it here just in case: my problem is the same as you described in your question. What I'm trying to know is how you fixed that. You mentioned that the problem was in soft threading and proper linux threads fixed that. And that is why I comment here: please tell a little bit more details about what is "proper linux threads"? Did you implement alienThreads for android build or make a fix for soft threads? – lpsun Jan 19 '15 at 12:54
  • 1
    Let me explain it to you little bit more in detail. In soft threading, the mutex is locked recursively such that the thread can be locked multiple times even if it is already locked, see this link for further mutex attributes : https://publib.boulder.ibm.com/iseries/v5r1/ic2924/index.htm?info/apis/users_55.htm . This recursive lock is being handled stricter with the introduction of ART , but was loosely handled with Dalvik . – learn_develop Jan 19 '15 at 16:00
  • 1
    So, we had to switch to using semaphores , and any subsequent function call to that thread would have to wait for the previous operation to complete and we always store the thread pointer to ensure we are always running on the initial thread we created. So, we ensure stricter thread checking compliant with ART, thereby preventing exceptions. Soft threading(mutex based) was completely discarded. – learn_develop Jan 19 '15 at 16:20
  • i'm sorry, i didn't catch this explanation: "we always store the thread pointer to ensure we are always running on the initial thread we created". Could you please write to me (contacts in profile). I will take only 5 min of your time and then I will return here and describe solutions for others. As I see I'm not only who stuck with this – lpsun Jan 19 '15 at 16:26
  • i suggest you're talking about picselLock mutex. But even it is not locked, I get StackOverflowError when using JNI from newly created soft thread. I have crash on startup actually. – lpsun Jan 19 '15 at 17:41
  • Hi @learn_develop, please answer :( I would be very appreciated if you give full answer with some examples how you fixed ART checking, because it is not clear for me what you changed – lpsun Jan 20 '15 at 14:30
  • If you believe we work on the same software, I might not be able to answer your query since it would be a licensed version of the software and my organization policies does not allow me to share more information than that. I wish I could have helped you. – learn_develop Jan 22 '15 at 09:35
  • yes, you are right (( I understand that, and that is why I even don't try to ask about source code or something like this. I only try to understand in general what you have done and what was the reason of problem. As I understood you didn't switch soft threads to native threads. You only make all calls from C code to JNI through the main thread? Am I right? – lpsun Jan 23 '15 at 12:21

1 Answers1

1

I would expect this problem has to do with a problem with references -- keeping a local reference around and using it on a different thread or something like that. I'm not sure what you meant by "native code calls into JNI to close the file", but perhaps you are passing a structure back to Java from JNI that needs to be flushed/released (so that the VM copies the data from the c structure back to the VM).

Apparently the ART has a few stricter jni checks than Dalvik. There is some detail on the Android site and further this page tells us how to debug them. You turn on checking for it on a real device using adb like this:

adb shell setprop debug.checkjni 1

Setting to to another value or rebooting the device will turn it off.

hack_on
  • 2,532
  • 4
  • 26
  • 30
  • 1
    Hi @hack: The problem was basically with soft threading the native code was using. Changing those to use proper linux threads fixed the issue. Your first two lines are relevant to the problem I was facing, so I am marking it as an answer. Thanks... – learn_develop Oct 28 '14 at 05:36
  • Hi @user3086861, could explain a little bit more about your solution with linux threads. If I'm right we are developing the same software. After changing soft threading with linux threads I have problems with timer thread. Actually with synchronization. Do you keep the timer implementation which was before for Android or implement new? or get it from linux build? Thank you! – lpsun Jan 18 '15 at 13:44
  • 1
    Hi @Ipsun : I am pretty sure we are not working on the same software :), my software not being an open source software. The idea is to ensure we are always running on the main thread, so we always store the current thread in our context and if the thread is already locked, wait till the thread is released before performing any other operation. – learn_develop Jan 19 '15 at 05:00
  • @learn_develop : do you mean you kept old soft-threading implementation? or implement alienThreads model as it is for other platforms? I'm trying to implement alienThreads for android L. But the problem with timer thread. How it should be implemented? Seems like you answered how it was before your fix – lpsun Jan 19 '15 at 07:00
  • What is the problem you are getting with timer threads altogether? It might be worth creating another question with the complete details so it might be easy to point out the problem. – learn_develop Jan 19 '15 at 07:41
  • Actually my problem is the same as you described in your question. What I'm trying to know is how you fixed that. You mentioned that the problem was in soft threading and proper linux threads fixed that. And that is why I comment here: please tell a little bit more details about what is "proper linux threads"? Did you implement alienThreads for android build or make a fix for soft threads? – lpsun Jan 19 '15 at 08:12