DetachCurrentThread causes a crash

5,001 views
Skip to first unread message

ezmora

unread,
Mar 31, 2011, 3:17:06 AM3/31/11
to android-ndk
I have a number of native threads which, from time to time, call Java
methods.
The sequence for calling a Java method is:

1. (*cached_jvm)->AttachCurrentThread(cached_jvm, (void*)&env, NULL);
2. Call Java method
3. (*cached_jvm)->DetachCurrentThread(cached_jvm);

This sequence of calls is repeated anytime a Java method needs to be
invoked, as long as the native thread is alive.
However, every now & then, when I call DetachCurrentThread(), the DVM
crashes with the following error:

03-30 14:07:08.636: ERROR/dalvikvm(24118): ERROR: detaching thread
with interp frames (count=18)
03-30 14:07:08.636: INFO/dalvikvm(24118): "main" prio=5 tid=1 RUNNABLE
03-30 14:07:08.636: INFO/dalvikvm(24118): | group="main" sCount=0
dsCount=0 obj=0x400c8690 self=0x115d8
03-30 14:07:08.636: INFO/dalvikvm(24118): | sysTid=24118 nice=0
sched=0/0 cgrp=default handle=-1343613840
03-30 14:07:08.636: INFO/dalvikvm(24118): | schedstat=( 2602101000
603072000 2458 ) utm=201 stm=59 core=1
03-30 14:07:08.636: INFO/dalvikvm(24118): at <my_package>(Native
Method)
03-30 14:07:08.636: INFO/dalvikvm(24118): at
android.os.AsyncTask.finish(AsyncTask.java:590)
03-30 14:07:08.636: INFO/dalvikvm(24118): at
android.os.AsyncTask.access$600(AsyncTask.java:149)
03-30 14:07:08.636: INFO/dalvikvm(24118): at android.os.AsyncTask
$InternalHandler.handleMessage(AsyncTask.java:603)
03-30 14:07:08.636: INFO/dalvikvm(24118): at
android.os.Handler.dispatchMessage(Handler.java:99)
03-30 14:07:08.636: INFO/dalvikvm(24118): at
android.os.Looper.loop(Looper.java:126)
03-30 14:07:08.636: INFO/dalvikvm(24118): at
android.app.ActivityThread.main(ActivityThread.java:3997)
03-30 14:07:08.636: INFO/dalvikvm(24118): at
java.lang.reflect.Method.invokeNative(Native Method)
03-30 14:07:08.636: INFO/dalvikvm(24118): at
java.lang.reflect.Method.invoke(Method.java:491)
03-30 14:07:08.636: INFO/dalvikvm(24118): at
com.android.internal.os.ZygoteInit
$MethodAndArgsCaller.run(ZygoteInit.java:841)
03-30 14:07:08.636: INFO/dalvikvm(24118): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
03-30 14:07:08.636: INFO/dalvikvm(24118): at
dalvik.system.NativeStart.main(Native Method)
03-30 14:07:08.636: ERROR/dalvikvm(24118): VM aborting
03-30 14:07:08.756: INFO/DEBUG(13268): *** *** *** *** *** *** *** ***
*** *** *** *** *** *** *** ***
03-30 14:07:08.756: INFO/DEBUG(13268): Build fingerprint: 'verizon/
trygon/stingray:3.0.1/HRI66/109065:user/release-keys'
03-30 14:07:08.756: INFO/DEBUG(13268): pid: 24118, tid: 24118 >>> ...
<<<
03-30 14:07:08.756: INFO/DEBUG(13268): signal 11 (SIGSEGV), code 1
(SEGV_MAPERR), fault addr deadd00d
03-30 14:07:08.756: INFO/DEBUG(13268): r0 fffffe78 r1 deadd00d r2
00000026 r3 00000000
03-30 14:07:08.756: INFO/DEBUG(13268): r4 800a2640 r5 800a2640 r6
00000000 r7 5631bc94
03-30 14:07:08.756: INFO/DEBUG(13268): r8 be835498 r9 5631bc7c 10
0000e140 fp fffffe90
03-30 14:07:08.756: INFO/DEBUG(13268): ip 800a2758 sp be8353a0 lr
afe6d515 pc 80044c20 cpsr 20000030
03-30 14:07:08.756: INFO/DEBUG(13268): d0 406c9483126e978d d1
3f50624dd2f1a9fc
03-30 14:07:08.766: INFO/DEBUG(13268): d2 3ffce61cf8e857c5 d3
4288000042640000
03-30 14:07:08.766: INFO/DEBUG(13268): d4 0000000000000000 d5
402e000000000000
03-30 14:07:08.766: INFO/DEBUG(13268): d6 7e37e43c8800759c d7
4000000000000000
03-30 14:07:08.766: INFO/DEBUG(13268): d8 3f800000422c0000 d9
4680000046800000
03-30 14:07:08.766: INFO/DEBUG(13268): d10 0000000042f20000 d11
0000000000000000
03-30 14:07:08.766: INFO/DEBUG(13268): d12 0000000000000000 d13
0000000000000000
03-30 14:07:08.766: INFO/DEBUG(13268): d14 0000000000000000 d15
0000000000000000
03-30 14:07:08.766: INFO/DEBUG(13268): scr 20000012
03-30 14:07:08.866: INFO/DEBUG(13268): #00 pc 00044c20 /
system/lib/libdvm.so (dvmAbort)
03-30 14:07:08.866: INFO/DEBUG(13268): #01 pc 0005244c /
system/lib/libdvm.so (dvmDetachCurrentThread)
03-30 14:07:08.866: INFO/DEBUG(13268): #02 pc 00047fea /
system/lib/libdvm.so

03-30 14:07:08.866: INFO/DEBUG(13268): code around pc:
03-30 14:07:08.866: INFO/DEBUG(13268): 80044c00 447a4479 f7d24c0b
2000eb50 ec66f7d2
03-30 14:07:08.866: INFO/DEBUG(13268): 80044c10 447c4809 6c1b5823
4798b103 22264902
03-30 14:07:08.866: INFO/DEBUG(13268): 80044c20 f7d2700a bf00ecb0
deadd00d 0004031c
03-30 14:07:08.866: INFO/DEBUG(13268): 80044c30 00041f21 0005da2a
fffffe78 4b09b40e
03-30 14:07:08.866: INFO/DEBUG(13268): 80044c40 4c09b517 aa05447b
f852591b 6b9b1b04
03-30 14:07:08.866: INFO/DEBUG(13268): code around lr:
03-30 14:07:08.866: INFO/DEBUG(13268): afe6d4f4 4a0e4b0d e92d447b
589c41f0 26004680
03-30 14:07:08.866: INFO/DEBUG(13268): afe6d504 686768a5 f9b5e006
b113300c 47c04628
03-30 14:07:08.866: INFO/DEBUG(13268): afe6d514 35544306 37fff117
6824d5f5 d1ef2c00
03-30 14:07:08.866: INFO/DEBUG(13268): afe6d524 e8bd4630 bf0081f0
0002803c ffffff8c
03-30 14:07:08.866: INFO/DEBUG(13268): afe6d534 b086b570 f602fb01
9004460c a804a901

AFAIK, DetachCurrentThread is called to free local references, and to
detach the Native thread from the VM.
Any idea why this call crashes the VM?

Igor R

unread,
Mar 31, 2011, 10:33:50 AM3/31/11
to andro...@googlegroups.com
> I have a number of native threads which, from time to time, call Java
> methods.
> The sequence for calling a Java method is:
>
> 1. (*cached_jvm)->AttachCurrentThread(cached_jvm, (void*)&env, NULL);
> 2. Call Java method
> 3. (*cached_jvm)->DetachCurrentThread(cached_jvm);
>
> This sequence of calls is repeated anytime a Java method needs to be
> invoked, as long as the native thread is alive.
> However, every now & then, when I call DetachCurrentThread(), the DVM
> crashes with the following error:

It's not a good idea to call attach/detach this way. In general,
DetachCurrentThread() should be called only when the thread is going
to exit. See the following discussion:
http://comments.gmane.org/gmane.comp.handhelds.android.ndk/4687

eyal zmora

unread,
Mar 31, 2011, 12:15:30 PM3/31/11
to andro...@googlegroups.com

Yes, I saw this discussion already. I'd like to have a deeper understanding of what detachCurrentThread does under the hood, why it causes a crash and why the crash is not consistent. Anyone?

> --
> You received this message because you are subscribed to the Google Groups "android-ndk" group.
> To post to this group, send email to andro...@googlegroups.com.
> To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.
>

fadden

unread,
Mar 31, 2011, 8:20:50 PM3/31/11
to android-ndk
On Mar 31, 9:15 am, eyal zmora <eyalzm...@gmail.com> wrote:
> Yes, I saw this discussion already. I'd like to have a deeper understanding
> of what detachCurrentThread does under the hood, why it causes a crash and
> why the crash is not consistent. Anyone?

This log message is the significant one:

ERROR/dalvikvm(24118): ERROR: detaching thread with interp frames
(count=18)

Your native function was called from a thread that had been executing
interpreted code. That is, something in interpreted code called your
native method, and then your method tried to detach the thread.
Because the thread might be holding mutexes (e.g. one of the methods
in the call chain was synchronized) or might have cleanup code in
"finally" blocks that is expected to run, you're not allowed to simply
detach the thread. You have to return all the way up the call stack
before you can do that.

In this case:

INFO/dalvikvm(24118): at <my_package>(Native Method)
INFO/dalvikvm(24118): at android.os.AsyncTask.finish(AsyncTask.java:
590)

Looks like you're trying to detach an async task thread.

alan

unread,
Apr 1, 2011, 4:06:48 AM4/1/11
to andro...@googlegroups.com
the following code should prevent this issue
  JNIEnv * env;
  bool attached = false;
  switch (vm->GetEnv((void**)&env, JNI_VERSION_1_6))
  {
  case JNI_OK:
    break;
  case JNI_EDETACHED:
    if (vm->AttachCurrentThread(&env, NULL)!=0)
    {
      throw std::runtime_error("Could not attach current thread");
    }
    attached = true;
    break;
  case JNI_EVERSION:
    throw std::runtime_error("Invalid java version");
  }
 
  .....
 
  if (attached)
  {
      jvm->DetachCurrentThread();
  }

Sergey Dryganets

unread,
Dec 11, 2017, 11:38:46 AM12/11/17
to android-ndk
On some Linux kernel versions, there is a bug in memory paging.
If I remember correctly we used JNI push and pop frame functions to manage the local references instead.

That helped to get rid of those crashes.
Reply all
Reply to author
Forward
0 new messages