简体   繁体   English

jni-应用程序崩溃

[英]jni - app crashing

This is a question related to the NDK and Android SDK. 这是与NDK和Android SDK有关的问题。 Currently, my C-code is calling a method defined in Java. 目前,我的C代码正在调用用Java定义的方法。 This method is called callFromNDK(). 此方法称为callFromNDK()。

Within this method, i am referencing an instance of the mediaplayer to play a short test tone. 在这种方法中,我引用媒体播放器的一个实例来播放简短的测试音。 callFromNDK() get's called every 2 secs. 每2秒调用一次callFromNDK()。 And the test tone itself is one sec. 测试音本身是一秒。

What i see is a (SIGSEGV), code 1 (SEGV_MAPERR), fault addr fffffff4 at times. 我看到的是(SIGSEGV),代码1(SEGV_MAPERR),有时是故障添加器fffffff4。

I am wondering if this is happening because the mediaplayer instance was created in a different context than the one that it's getting used in? 我想知道是否正在发生这种情况,因为mediaplayer实例是在与使用它所使用的上下文不同的上下文中创建的?

Here's the relevant piece of code [Java file] 这是相关的代码[Java文件]

public class Canvastutorial extends Activity {
    private static MediaPlayer mediaPlayer = null;
    public void callFromNDK() {
        if (mediaPlayer != null) {
            mediaPlayer.start();
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.audioclip);
        mediaPlayer.setLooping(false);
    }

    @Override
    protected void onDestroy() {
        mediaPlayer.release();
        mediaPlayer = null;
        System.gc();
        super.onDestroy();
    }

    @Override
    protected void onPause() {
        stopAndPrepare();
        super.onPause();
    }   

    private void stopAndPrepare() {
            mediaPlayer.stop();
            try {
                mediaPlayer.prepare();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mediaPlayer.seekTo(0);
    }
}

The LogCat is as below when the app crashes: 应用崩溃时,LogCat如下所示:

04-27 10:42:13.228: I/DEBUG(8926): Build fingerprint: 'google/passion/passion:2.3.6/GRK39F/189904:user/release-keys'
04-27 10:42:13.228: I/DEBUG(8926): pid: 10362, tid: 11222  >>> <package_name> <<<
04-27 10:42:13.228: I/DEBUG(8926): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr fffffff4
04-27 10:42:13.238: I/DEBUG(8926):  r0 4214cdc0  r1 00000000  r2 00000000  r3 0000ce68
04-27 10:42:13.238: I/DEBUG(8926):  r4 44628398  r5 00000000  r6 4472fbd8  r7 0000000e
04-27 10:42:13.238: I/DEBUG(8926):  r8 80018000  r9 00000000  10 00000000  fp 800a5368
04-27 10:42:13.238: I/DEBUG(8926):  ip 00000000  sp 4472fb88  lr 8001d084  pc 8001d090  cpsr 60000010
04-27 10:42:13.238: I/DEBUG(8926):  d0  00650072006800b8  d1  00000044bed7f457
04-27 10:42:13.238: I/DEBUG(8926):  d2  0069006400650052  d3  004d0049002e0040
04-27 10:42:13.238: I/DEBUG(8926):  d4  0061006900640065  d5  00790061006c0050
04-27 10:42:13.238: I/DEBUG(8926):  d6  0065005300720065  d7  0063006900760072
04-27 10:42:13.238: I/DEBUG(8926):  d8  0000000000000000  d9  0000000042ba56de
04-27 10:42:13.238: I/DEBUG(8926):  d10 0000000000000000  d11 0000000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d12 0000000000000000  d13 0000000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d14 0000000000000000  d15 0000000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d16 0000000000000001  d17 c053000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d18 0000000000000000  d19 0000000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d20 3ff0000000000000  d21 8000000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d22 0000000000000000  d23 ff00000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d24 ff00000000000000  d25 ff00000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d26 0100010001000100  d27 0100010001000100
04-27 10:42:13.238: I/DEBUG(8926):  d28 0100010001000100  d29 3ff0000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d30 0000000000000000  d31 3ff0000000000000
04-27 10:42:13.238: I/DEBUG(8926):  scr 60000012
04-27 10:42:13.328: I/DEBUG(8926):          #00  pc 0001d090  /system/lib/libdvm.so
04-27 10:42:13.328: I/DEBUG(8926):          #01  pc 000220e4  /system/lib/libdvm.so
04-27 10:42:13.328: I/DEBUG(8926):          #02  pc 00020fdc  /system/lib/libdvm.so
04-27 10:42:13.328: I/DEBUG(8926):          #03  pc 0005fc40  /system/lib/libdvm.so
04-27 10:42:13.328: I/DEBUG(8926):          #04  pc 0004cff8  /system/lib/libdvm.so
04-27 10:42:13.328: I/DEBUG(8926):          #05  pc 00001590  /data/data/<package_name>/lib/libtest-jni.so
04-27 10:42:13.328: I/DEBUG(8926):          #06  pc 000016ca  /data/data/<package_name>/lib/libtest-jni.so
04-27 10:42:13.328: I/DEBUG(8926):          #07  pc 000118e4  /system/lib/libc.so
04-27 10:42:13.328: I/DEBUG(8926):          #08  pc 000114b0  /system/lib/libc.so
04-27 10:42:13.328: I/DEBUG(8926): code around pc:
04-27 10:42:13.328: I/DEBUG(8926): 8001d070 fa0108cc ea000017 e3a00001 e3a09000 
04-27 10:42:13.328: I/DEBUG(8926): 8001d080 ebffff72 e2450014 e5905000 e5909004 
04-27 10:42:13.328: I/DEBUG(8926): 8001d090 e515200c e5963018 e3520000 1592a000 
04-27 10:42:13.328: I/DEBUG(8926): 8001d0a0 e3a01000 0affff8a e1f970b6 e5862010 
04-27 10:42:13.328: I/DEBUG(8926): 8001d0b0 e59a1028 e5835028 e590a010 e1a04009 
04-27 10:42:13.328: I/DEBUG(8926): code around lr:
04-27 10:42:13.328: I/DEBUG(8926): 8001d064 e088f30c e1a01000 e5960018 fa0108cc 
04-27 10:42:13.328: I/DEBUG(8926): 8001d074 ea000017 e3a00001 e3a09000 ebffff72 
04-27 10:42:13.328: I/DEBUG(8926): 8001d084 e2450014 e5905000 e5909004 e515200c 
04-27 10:42:13.328: I/DEBUG(8926): 8001d094 e5963018 e3520000 1592a000 e3a01000 
04-27 10:42:13.328: I/DEBUG(8926): 8001d0a4 0affff8a e1f970b6 e5862010 e59a1028 
04-27 10:42:13.328: I/DEBUG(8926): stack:
04-27 10:42:13.328: I/DEBUG(8926):     4472fb48  4472fbe0  
04-27 10:42:13.328: I/DEBUG(8926):     4472fb4c  4214cce4  
04-27 10:42:13.328: I/DEBUG(8926):     4472fb50  0000ce60  
04-27 10:42:13.328: I/DEBUG(8926):     4472fb54  00000001  
04-27 10:42:13.328: I/DEBUG(8926):     4472fb58  4472fbe0  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb5c  80049697  /system/lib/libdvm.so
04-27 10:42:13.338: I/DEBUG(8926):     4472fb60  4214cce4  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb64  431fbec9  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb68  ad34675d  /system/lib/libandroid_runtime.so
04-27 10:42:13.338: I/DEBUG(8926):     4472fb6c  4472fbe0  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb70  42f8e91e  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb74  4214cd00  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb78  4472fbd8  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb7c  40038360  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb80  df002777  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb84  e3a070ad  
04-27 10:42:13.338: I/DEBUG(8926): #00 4472fb88  4214e32c  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb8c  4472fbd8  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb90  00000001  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb94  002c2c40  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb98  0000ce68  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb9c  000f45b8  
04-27 10:42:13.338: I/DEBUG(8926):     4472fba0  800aad38  
04-27 10:42:13.338: I/DEBUG(8926):     4472fba4  fffffe84  
04-27 10:42:13.338: I/DEBUG(8926):     4472fba8  800a5368  
04-27 10:42:13.338: I/DEBUG(8926):     4472fbac  800220e8  /system/lib/libdvm.so
04-27 10:42:13.338: I/DEBUG(8926): #01 4472fbb0  4472fbd8  
04-27 10:42:13.338: I/DEBUG(8926):     4472fbb4  0000ce60  
04-27 10:42:13.338: I/DEBUG(8926):     4472fbb8  80022058  /system/lib/libdvm.so
04-27 10:42:13.338: I/DEBUG(8926):     4472fbbc  423298c8  
04-27 10:42:13.338: I/DEBUG(8926):     4472fbc0  00000000  
04-27 10:42:13.338: I/DEBUG(8926):     4472fbc4  80020fe0  /system/lib/libdvm.so

Any idea is appreciated. 任何想法表示赞赏。

Thanks. 谢谢。

The native side of the project: The thread_function get's called periodically (2 sec interval) and that's where i am calling the function defined in Java code. 项目的本机方面:定期(每2秒间隔)调用thread_function get,这就是我正在调用Java代码中定义的函数的地方。

// Callbacks to Android
JavaVM *j_vm;
jobject *j_obj;
JNIEnv *j_env;
jclass j_cls;
jmethodID android_call;

int JNI_OnLoad(JavaVM* vm, void* reserved) {
    j_vm = vm;
    (*j_vm)->GetEnv(j_vm, (void**) &j_env, JNI_VERSION_1_6);
    j_cls = (*j_env)->FindClass(j_env, "<package_name>/<class_name>");
    android_call = (*j_env)->GetMethodID(j_env, j_cls, "callFromNDK", "()V");
    j_obj = (*j_env)->NewGlobalRef(j_env, (*j_env)->NewObject(j_env, j_cls, android_call));
    return JNI_VERSION_1_6;
}

void JNI_OnUnload(JavaVM *vm, void *reserved) {
    (*j_env)->DeleteGlobalRef(j_env, j_obj);
}

void *thread_function(void *ptr) {
    int *which = (int *) ptr;
    (*j_vm)->AttachCurrentThread(j_vm, &j_env, NULL);
    int rc;
    while (!stop_thread) {
        rc = pthread_mutex_lock(&mtx);
        rc = pthread_cond_wait(&cond, &mtx);
        rc = pthread_mutex_unlock(&mtx);
        if (!stop_thread) {
            (*j_env)->CallVoidMethod(j_env, j_obj, android_call);
        }
    }
    (*j_vm)->DetachCurrentThread(j_vm);
    return NULL;
}

Have you tried running it in an emulator? 您是否尝试过在模拟器中运行它? Since it crashed in libdvm you would probably get some very useful logging just before the native crash. 由于它在libdvm中崩溃,因此您可能会在本机崩溃之前获得一些非常有用的日志记录。

The problem could be the following line: 问题可能是以下几行:

j_cls = (*j_env)->FindClass(j_env, "<package_name>/<class_name>");

Is it safe to assume you replaced "<package_name>/<class_name>" with the actual namespace and class name? 是否可以安全地假设您用实际的名称空间和类名称替换了"<package_name>/<class_name>"

By eye I see three errors in this code, but run with CheckJNI (http://android-developers.blogspot.com/2011/07/debugging-android-jni-with-checkjni.html) and Dalvik should tell you what you've done wrong. 肉眼我看到此代码中的三个错误,但与CheckJNI(http://android-developers.blogspot.com/2011/07/debugging-android-jni-with-checkjni.html)一起运行时,Dalvik应该告诉您您做错了。 (You should run with the latest release to get the best checking. One of the mistakes I noticed won't be spotted by Gingerbread [and you'll get away with it in Gingerbread too].) (您应该使用最新版本来进行最好的检查。我发现的错误之一不会被Gingerbread发现(并且您也将在Gingerbread中摆脱它)。)

You should always use CheckJNI while developing and debugging. 在开发和调试时,应始终使用CheckJNI。 StackOverflow should probably make people check a "yes, I tried CheckJNI" box before posting any question containing the word JNI :-) 在发布任何包含单词JNI的问题之前,StackOverflow可能应该使人们选中“是的,我尝试了CheckJNI”框:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM