Android and JNI_OnLoad crash on device
I am new to working with JNI on Android and I am writing an application that requires a JNI_OnLoad implementation. I have browsed the internet for help and it seems that there are many different documents in conflict about how this function should be implemented. However, I went with a method that seemed to work on my emulator, but not on my device.
LogCat produces the following:
D/dalvikvm(11317): Trying to load lib /data/app/libHelloAndroid.so 0xb6db9f50
D/dalvikvm(11317): Added shared lib /data/app/libHelloAndroid.so 0xb6db9f50
I/DEBUG ( 1244): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 1244): Build fingerprint: 'generic/mfld_cdk/mfld_cdk:2.3.3/GRI40/eng.gerrit2.20110607.120237:eng/test-keys'
I/DEBUG ( 1244): pid: 11317, tid: 11317 >>> com.example.helloandroid <<<
I/DEBUG ( 1244): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000001
I/DEBUG ( 1244): eax 09353b90 ebx 8293910c ecx 00000300 edx 00000001
I/DEBUG ( 1244): esi 094313e0 edi 84400395
I/DEBUG ( 1244): xcs 00000073 xds 0000007b xes 0000007b xfs 00000000 xss 0000007b
I/DEBUG ( 1244): eip 8440039d ebp bf859e70 esp bf859e00 flags 00010206
I/DEBUG ( 1244): #00
I/DEBUG ( 1244): eip: 8440039d /data/app/libHelloAndroid.so (JNI_OnLoad)
I/DEBUG ( 1244): #01
I/DEBUG ( 1244): eip: 828a8df9 /system/lib/libdvm.so (Dalvik_java_lang_Runtime_nativeLoad)
I/DEBUG ( 1244): #02
I/DEBUG ( 1244): eip: 82831cd9 /system/lib/libdvm.so
I/DEBUG ( 1244): #03
I/DEBUG ( 1244): eip: b680ec7c
I/DEBUG ( 1244): #04
I/DEBUG ( 1244): eip: 0004011a
I/DEBUG ( 1244): #05
I/DEBUG ( 1244): eip: ffffffff
I/DEBUG ( 1244): #06
I/DEBUG ( 1244): eip: ffffffff
I/DEBUG ( 1244): #07
I/DEBUG ( 1244): eip: ffffffff
I/DEBUG ( 1244): stack:
I/DEBUG ( 1244): #00
I/DEBUG ( 1244): bf859e00 a901b083
I/DEBUG ( 1244): bf859e04 8287da14 /system/lib/libdvm.so (dvmLoadNativeCode)
I/DEBUG ( 1244): bf859e08 09353b90 [heap] (dvmLoadNativeCode)
I/DEBUG ( 1244): bf859e0c 00000000 (dvmLoadNativeCode)
I/DEBUG ( 1244): bf859e10 8291f9bf /system/lib/libdvm.so
I/DEBUG ( 1244): bf859e14 094313e0 [heap]
I/DEBUG ( 1244): bf859e18 b6db9f50 /dev/ashmem/dalvik-heap (deleted)
I/DEBUG ( 1244): bf859e1c 8293910c /system/lib/libdvm.so
I/DEBUG ( 1244): bf859e20 bf859e70 [stack]
I/DEBUG ( 1244): bf859e24 82888b77 /system/lib/libdvm.so (dvmCreateCstrFromString)
I/DEBUG ( 1244): bf859e28 0000001d (dvmCreateCstrFromString)
I/DEBUG ( 1244): bf859e2c bf859ea0 [stack] (dvmCreateCstrFromString)
I/DEBUG ( 1244): bf859e30 b632ea84 /dev/ashmem/dalvik-LinearAlloc (deleted) (dvmCreateCstrFromString)
I/DEBUG ( 1244): bf859e34 00000001 (dvmCreateCstrFromString)
I/DEBUG ( 1244): bf859e38 00000000 (dvmCreateCstrFromString)
I/DEBUG ( 1244): bf859e3c 09431418 [heap] (dvmCreateCstrFromString)
I/DEBUG ( 1244): ...... ......
I/DEBUG ( 1244): #01
I/DEBUG ( 1244): bf859e74 828a8df9 /system/lib/libdvm.so (Dalvik_java_lang_Runtime_nativeLoad)
I/DEBUG ( 1244): bf859e78 094313e0 [heap] (Dalvik_java_lang_Runtime_nativeLoad)
I/DEBUG ( 1244): bf859e7c b6db9f50 /dev/ashmem/dalvik-heap (deleted) (Dalvik_java_lang_Runtime_nativeLoad)
I/DEBUG ( 1244): bf859e80 bf859e94 [stack] (Dalvik_java_lang_Runtime_nativeLoad)
I/DEBUG ( 1244): bf859e84 b55611c2 /data/dalvik-cache/data@app@com.example.helloandroid-2.apk@classes.dex (Dalvik_java_lang_Runtime_nativeLoad)
I/DEBUG ( 1244): bf859e88 8289ac09 /system/lib/libdvm.so (dvmGetCaller2Class)
I/DEBUG ( 1244): bf859e8c 8293910c /system/lib/libdvm.so (dvmGetCaller2Class)
I/DEBUG ( 1244): bf859e90 bf859eb0 [stack] (dvmGetCaller2Class)
I/DEBUG ( 1244): bf859e94 00000000 (dvmGetCaller2Class)
I/DEBUG ( 1244): bf859e98 b680ec3c (dvmGetCaller2Class)
I/DEBUG ( 1244): bf859e9c b680eb78 (dvmGetCaller2Class)
I/DEBUG ( 1244): bf859ea0 094314e0 [heap] (dvmGetCaller2Class)
I/DEBUG ( 1244): bf859ea4 00000020 (dvmGetCaller2Class)
I/DEBUG ( 1244): bf859ea8 b5fa27fc /data/dalvik-cache/system@framework@core.jar@classes.dex (dvmGetCaller2Class)
I/DEBUG ( 1244): bf859eac b680ec24 (dvmGetCaller2Class)
I/DEBUG ( 1244): bf859eb0 bf859f50 [stack] (dvmGetCaller2Class)
I/DEBUG ( 1244): ...... ......
I/DEBUG ( 1244): #02
I/DEBUG ( 1244): bf859eb4 82831cd9 /system/lib/libdvm.so
I/DEBUG ( 1244): bf859eb8 b680ec04
I/DEBUG ( 1244): bf859ebc bf859f58 [stack]
I/DEBUG ( 1244): bf859ec0 b63f8f60 /dev/ashmem/dalvik-LinearAlloc (deleted)
I/DEBUG ( 1244): bf859ec4 09355e68 [heap]
I/DEBUG ( 1244): bf859ec8 b6dbcfa8 /dev/ashmem/dalvik-heap (deleted)
I/DEBUG ( 1244): bf859ecc 09355e68 [heap]
I/DEBUG ( 1244): bf859ed0 b680ebec
I/DEBUG ( 1244): bf859ed4 09355e68 [heap]
I/DEBUG ( 1244): bf859ed8 bf859f4c [stack]
I/DEBUG ( 1244): bf859edc 00000000
I/DEBUG ( 1244): bf859ee0 82c03d68
I/DEBUG ( 1244): bf859ee4 00002000
I/DEBUG ( 1244): bf859ee8 bf859e14 [stack]
I/DEBUG ( 1244): bf859eec bf859f50 [stack]
I/DEBUG ( 1244): bf859ef0 bf859f50 [stack]
I/DEBUG ( 1244): ...... ......
I/DEBUG ( 1244): #03
I/DEBUG ( 1244): #04
I/DEBUG ( 1244): b5560980 0004011a
I/DEBUG ( 1244): b5560984 00022071
I/DEBUG ( 1244): b5560988 001a0010
I/DEBUG ( 1244): b556098c 10710001
I/DEBUG ( 1244): b5560990 00000027
I/DEBUG ( 1244): b5560994 0034001a
I/DEBUG ( 1244): b5560998 0035011a
I/DEBUG ( 1244): b556099c 00022071
I/DEBUG ( 1244): b55609a0 000e0010
I/DEBUG ( 1244): b55609a4 00010002
I/DEBUG ( 1244): b55609a8 00000002
I/DEBUG ( 1244): b55609ac 00001358
I/DEBUG ( 1244): b55609b0 0000000b
I/DEBUG ( 1244): b55609b4 00001070
I/DEBUG ( 1244): b55609b8 00220001
I/DEBUG ( 1244): b55609bc 2070000c
I/DEBUG ( 1244): ...... ......
I/DEBUG ( 1244): #05
I/DEBUG ( 1244): #06
I/DEBUG ( 1244): #07
Below is my implementation of JNI_OnLoad ...
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
LOGI("Executing JNI_OnLoad");
JNIEnv *env;
jint onLoad_err = -1;
jclass k;
static const char* const strClassName="com/example/helloandroid/HelloAndroid";
cached_jvm = vm;
// Checks JNI version
if((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK){
LOGE("JNI Check failure");
return onLoad_err;
}
// Checks if environment is null
if (env == NULL) {
LOGE("Env is NULL");
return onLoad_err;
}
k = (*env)->FindClass(env, strClassName);
if(k == NULL){
LOGE("Find Class returns NULL");
return onLoad_err;
}
if ((*env)->RegisterNatives(env, k, methods, sizeof(methods)/sizeof(methods[0])) != JNI_OK){
LOGE("Method registration failure");
return onLoad_err;
}
LOGI("Successfully executed JNI_onLoad");
return JNI_VERSION_1_4;
}
Is there something special about native code that makes it act differently on the emulator than on the device itself? Or do I need to do more in JNI_OnLoad?
Thanks in advance!
+2
source to share