As far as I know, Everything point to a buggy implementation of
NewWeakGlobalRef() on Android (all version).
Let's consider this simplest code.
It calls java.lang.String.length() from C++.
/*
* Class: org_karlsland_MainActivity
* Method: call_native_code
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_org_karlsland_MainActivity_call_1native_1code
(JNIEnv* env, jclass clazz)
{
__android_log_print (ANDROID_LOG_INFO, "NativeCode", "NativeCode
is called.");
jclass string_class = env->FindClass ("java/lang/String");
jobject string_obj = env->NewStringUTF ("Hello World");
jmethodID string_length = env->GetMethodID (string_class,
"length", "()I");
jweak global_string_obj = env->NewWeakGlobalRef(string_obj);
__android_log_print (ANDROID_LOG_INFO, "NativeCode",
"string_class = %p.", string_class);
__android_log_print (ANDROID_LOG_INFO, "NativeCode",
"string_obj = %p.", string_obj);
__android_log_print (ANDROID_LOG_INFO, "NativeCode",
"string_length = %p.", string_length);
__android_log_print (ANDROID_LOG_INFO, "NativeCode",
"global_string_obj = %p.", global_string_obj);
int len;
len = env->CallIntMethod (string_obj, string_length);
__android_log_print (ANDROID_LOG_INFO, "NativeCode",
"String.length = %d.", len);
len = env->CallIntMethod (global_string_obj, string_length);
__android_log_print (ANDROID_LOG_INFO, "NativeCode",
"String.length = %d.", len);
}
And this works fine at least in Ubuntu 10.10.
But in Android, this always crash with SIGSEGV when env-
>CallIntMethod() is invoked (which uses jweak value).
And fault address(0xdae1b6bf) indicates just jweak value returned by
env->NewWeakGlobalRef().
04-25 01:36:31.374: INFO/NativeCode(5406): NativeCode is called.
04-25 01:36:31.374: INFO/NativeCode(5406): string_class =
0x4000d1c8.
04-25 01:36:31.385: INFO/NativeCode(5406): string_obj =
0x44ee48e0.
04-25 01:36:31.385: INFO/NativeCode(5406): string_length =
0x4188786c.
04-25 01:36:31.385: INFO/NativeCode(5406): global_string_obj =
0xdae1b6bf.
04-25 01:36:31.394: INFO/NativeCode(5406): String.length = 11.
04-25 01:36:31.514: INFO/DEBUG(31): *** *** *** *** *** *** *** ***
*** *** *** *** *** *** *** ***
04-25 01:36:31.514: INFO/DEBUG(31): Build fingerprint: 'generic/sdk/
generic/:2.2/FRF91/43546:eng/test-keys'
04-25 01:36:31.524: INFO/DEBUG(31): pid: 5406, tid: 5406 >>>
org.karlsland <<<
04-25 01:36:31.524: INFO/DEBUG(31): signal 11 (SIGSEGV), fault addr
dae1b6bf
04-25 01:36:31.544: INFO/DEBUG(31): r0 00000007 r1 4188786c r2
4188786c r3 bec06854
04-25 01:36:31.544: INFO/DEBUG(31): r4 dae1b6bf r5 0000ccb0 r6
4188786c r7 bec06854
04-25 01:36:31.564: INFO/DEBUG(31): r8 4000d1c8 r9 dae1b6bf 10
0000ce04 fp 4186bce0
04-25 01:36:31.564: INFO/DEBUG(31): ip 80888110 sp bec067d8 lr
80846dad pc 80840d8e cpsr 00000030
Say again, I'm sure that weak global reference on Android doesn't
work.
Do you have any idea?