【问题标题】:NDK : Problems with VM aborting and Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1)NDK:VM 中止和致命信号 11 (SIGSEGV) 在 0xdeadd00d (code=1) 的问题
【发布时间】:2014-12-30 09:03:20
【问题描述】:

我正在使用来自 LITTLE ENDIAN 的 SpectrumWorx Melodify SDK, 但是这些天这些问题真的让我很困惑。

当我尝试通过 Activity 而不是 ANativeActivity 使用 Melodify SDK 时,出现了问题。 在 doc API 中,我们应该首先设置AppContext,如下代码:

void    setAppContext (::ANativeActivity const &,::ndk_helper::JNIHelper const &)
void    setAppContext (::ANativeActivity const &)
void    setAppContext (::JavaVM &,::jobject activity,::jobject assetManager)
void    setAppContext (::JavaVM &,::jobject activity)

所以我从这个example.cpp开始:

#include "le/audioio/device.hpp"
#include "le/audioio/file.hpp"
#include "le/audioio/outputWaveFile.hpp"

#include "le/melodify/melodifyer.hpp"

#include "le/utility/entryPoint.hpp"
#include "le/utility/filesystem.hpp"
#include "le/utility/trace.hpp"
#include "le/utility/sleep.hpp"

#include <jni.h>
#include <android/log.h>

#define  LOG_TAG    "testjni"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

static JavaVM *g_VM;

extern "C" {
    JNIEXPORT void JNICALL Java_com_example_ledemo_MainActivity_javaCallJNI(JNIEnv*   env, jobject obj);
};

jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    JNIEnv* env;
    if (vm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK)
        return -1;
    g_VM = vm;
    LOGI("JNI INIT");
    return JNI_VERSION_1_6;
}

JNIEXPORT void JNICALL Java_com_example_ledemo_MainActivity_javaCallJNI(JNIEnv* env, jobject obj)
{
   LOGI("JNI work !");

    jclass clazz = env->FindClass("com/example/ledemo/MainActivity");
    if (clazz == 0) {
        LOGI("FindClass error");
        return;
    }
    jmethodID javamethod = env->GetMethodID(clazz, "callFromCPP", "()V");
    if (javamethod == 0) {
        LOGI("GetMethodID error");
        return;
    }
    env->CallVoidMethod(obj, javamethod);
    using namespace LE;
    LE::Utility::setAppContext(*g_VM, clazz);
    LOGI("setContext finish");
    }   

但是logcat报错:

12-30 15:15:34.251: A/SpectrumWorx SDK assertion failure(8638): methodGetAssets (271)
12-30 15:15:34.251: A/libc(8638): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 8638 (.example.ledemo)**strong text** 

我试试这个代码:

#include "le/audioio/device.hpp"
#include "le/audioio/file.hpp"
#include "le/audioio/outputWaveFile.hpp"

#include "le/melodify/melodifyer.hpp"

#include "le/utility/entryPoint.hpp"
#include "le/utility/filesystem.hpp"
#include "le/utility/trace.hpp"
#include "le/utility/sleep.hpp"

#include <jni.h>
#include <android/log.h>
#include <assert.h>
// for native asset manager
#include <sys/types.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>

#define  LOG_TAG    "testjni"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

static JavaVM *g_VM;
static jobject gActivity;

extern "C" {
JNIEXPORT void JNICALL Java_com_example_ledemo_MainActivity_javaCallJNI(JNIEnv* env,         jobject obj);
};

jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    JNIEnv* env;
    if (vm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK)
        return -1;
    g_VM = vm;
    LOGI("JNI INIT");

    return JNI_VERSION_1_6;
}

JNIEXPORT void JNICALL Java_com_example_ledemo_MainActivity_javaCallJNI(JNIEnv* env, jobject obj)
{
    LOGI("JNI work !");

    jclass clazz = env->FindClass("com/example/ledemo/MainActivity");
    if (clazz == 0) {
        LOGI("FindClass error");
        return;
    }
    jmethodID javamethod = env->GetMethodID(clazz, "callFromCPP", "()V");
    if (javamethod == 0) {
        LOGI("GetMethodID error");
        return;
    }
    env->CallVoidMethod(obj, javamethod);

    gActivity = (jobject)env->NewGlobalRef(clazz);

}

extern "C" void  Java_com_example_ledemo_MainActivity_setJNI(JNIEnv* env, jclass         clazz, jobject assetManager)
{
    using namespace LE;
    LE::Utility::setAppContext(*g_VM, gActivity, assetManager);
    LOGI("setContext finish");
} 

这是我的 Java 代码:

package com.example.ledemo;

import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {

    Button btn;

    static AssetManager assetManager;
    Activity activity;

    public native void javaCallJNI();
    public native void setJNI(AssetManager assetManager);

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        assetManager = getAssets();

        Log.i("onCreate", "Native function begining");
        javaCallJNI();
        Log.i("onCreate", "Native function ending");

        btn = (Button) findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View view) {

            setJNI(assetManager);   
        }
    });
}

void callFromCPP() {
    Log.i("callFromCPP", "JNI can call JAVA !");
    return ;
}

问题依旧:

12-30 15:55:12.646: I/testjni(12862): JNI INIT
12-30 15:55:12.694: I/onCreate(12862): Native function begining
12-30 15:55:12.694: I/testjni(12862): JNI work !
12-30 15:55:12.694: I/callFromCPP(12862): JNI can call JAVA !
12-30 15:55:12.695: I/onCreate(12862): Native function ending

12-30 15:55:33.327: W/dalvikvm(12862): JNI WARNING: JNI method called with exception pending
12-30 15:55:33.328: W/dalvikvm(12862):              in Lcom/example/ledemo/MainActivity;.setJNI:(Landroid/content/res/AssetManager;)V (CallObjectMethodV)
12-30 15:55:33.328: W/dalvikvm(12862): Pending exception is:
12-30 15:55:33.328: I/dalvikvm(12862): java.lang.NoSuchMethodError: no method with name='getFilesDir' signature='()Ljava/io/File;' in class Ljava/lang/Class;
12-30 15:55:33.328: I/dalvikvm(12862):  at com.example.ledemo.MainActivity.setJNI(Native Method)
12-30 15:55:33.328: I/dalvikvm(12862):  at com.example.ledemo.MainActivity$1.onClick(MainActivity.java:49)
12-30 15:55:33.328: I/dalvikvm(12862):  at android.view.View.performClick(View.java:4211)
12-30 15:55:33.328: I/dalvikvm(12862):  at android.view.View$PerformClick.run(View.java:17446)
12-30 15:55:33.328: I/dalvikvm(12862):  at android.os.Handler.handleCallback(Handler.java:725)
12-30 15:55:33.328: I/dalvikvm(12862):  at android.os.Handler.dispatchMessage(Handler.java:92)
12-30 15:55:33.328: I/dalvikvm(12862):  at android.os.Looper.loop(Looper.java:153)
12-30 15:55:33.329: I/dalvikvm(12862):  at android.app.ActivityThread.main(ActivityThread.java:5297)
12-30 15:55:33.329: I/dalvikvm(12862):  at java.lang.reflect.Method.invokeNative(Native Method)
12-30 15:55:33.329: I/dalvikvm(12862):  at java.lang.reflect.Method.invoke(Method.java:511)
12-30 15:55:33.329: I/dalvikvm(12862):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
12-30 15:55:33.329: I/dalvikvm(12862):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
12-30 15:55:33.329: I/dalvikvm(12862):  at dalvik.system.NativeStart.main(Native Method)
12-30 15:55:33.329: I/dalvikvm(12862): "main" prio=5 tid=1 NATIVE
12-30 15:55:33.330: I/dalvikvm(12862):   | group="main" sCount=0 dsCount=0 obj=0x415a3a30 self=0x41592f10
12-30 15:55:33.330: I/dalvikvm(12862):   | sysTid=12862 nice=0 sched=0/0 cgrp=apps handle=1074337884
12-30 15:55:33.330: I/dalvikvm(12862):   | state=R schedstat=( 267627914 199014395 585 ) utm=19 stm=7 core=0
12-30 15:55:33.372: I/dalvikvm(12862):   #00  pc 000012a0  /system/lib/libcorkscrew.so (unwind_backtrace_thread+27)
12-30 15:55:33.372: I/dalvikvm(12862):   #01  pc 0006118e  /system/lib/libdvm.so (dvmDumpNativeStack(DebugOutputTarget const*, int)+53)
12-30 15:55:33.372: I/dalvikvm(12862):   #02  pc 00054aaa  /system/lib/libdvm.so (dvmDumpThreadEx(DebugOutputTarget const*, Thread*, bool)+329)
12-30 15:55:33.372: I/dalvikvm(12862):   #03  pc 00054b4a  /system/lib/libdvm.so (dvmDumpThread(Thread*, bool)+25)
12-30 15:55:33.372: I/dalvikvm(12862):   #04  pc 00038eba  /system/lib/libdvm.so
12-30 15:55:33.373: I/dalvikvm(12862):   #05  pc 00040f92  /system/lib/libdvm.so
12-30 15:55:33.373: I/dalvikvm(12862):   #06  pc 0002b0f8  /data/app-lib/com.example.ledemo-2/liblittle-effect.so
12-30 15:55:33.373: I/dalvikvm(12862):   #07  pc 0002ad34  /data/app-lib/com.example.ledemo-2/liblittle-effect.so
12-30 15:55:33.373: I/dalvikvm(12862):   #08  pc 000066fe  /data/app-lib/com.example.ledemo-2/liblittle-effect.so     (Java_com_example_ledemo_MainActivity_setJNI+13)
12-30 15:55:33.373: I/dalvikvm(12862):   #09  pc 0001e4d0  /system/lib/libdvm.so (dvmPlatformInvoke+112)
12-30 15:55:33.373: I/dalvikvm(12862):   #10  pc 0004ddf8  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+499)
12-30 15:55:33.374: I/dalvikvm(12862):   #11  pc 00050190  /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+171)
12-30 15:55:33.374: I/dalvikvm(12862):   #12  pc 000278a0  /system/lib/libdvm.so
12-30 15:55:33.374: I/dalvikvm(12862):   #13  pc 0002b804  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+180)
12-30 15:55:33.374: I/dalvikvm(12862):   #14  pc 000613ce  /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+373)
12-30 15:55:33.374: I/dalvikvm(12862):   #15  pc 000692e8  /system/lib/libdvm.so
12-30 15:55:33.374: I/dalvikvm(12862):   #16  pc 000278a0  /system/lib/libdvm.so
12-30 15:55:33.375: I/dalvikvm(12862):   #17  pc 0002b804  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+180)
12-30 15:55:33.375: I/dalvikvm(12862):   #18  pc 000610a8  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+271)
12-30 15:55:33.375: I/dalvikvm(12862):   #19  pc 0004a0d0  /system/lib/libdvm.so
12-30 15:55:33.375: I/dalvikvm(12862):   #20  pc 0004d126  /system/lib/libandroid_runtime.so
12-30 15:55:33.375: I/dalvikvm(12862):   #21  pc 0004decc  /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, char const*)+399)
12-30 15:55:33.375: I/dalvikvm(12862):   #22  pc 00000db6  /system/bin/app_process
12-30 15:55:33.376: I/dalvikvm(12862):   #23  pc 0001bd98  /system/lib/libc.so (__libc_init+64)
12-30 15:55:33.376: I/dalvikvm(12862):   at com.example.ledemo.MainActivity.setJNI(Native Method)
12-30 15:55:33.376: I/dalvikvm(12862):   at com.example.ledemo.MainActivity$1.onClick(MainActivity.java:49)
12-30 15:55:33.377: I/dalvikvm(12862):   at android.view.View.performClick(View.java:4211)
12-30 15:55:33.377: I/dalvikvm(12862):   at android.view.View$PerformClick.run(View.java:17446)
12-30 15:55:33.377: I/dalvikvm(12862):   at android.os.Handler.handleCallback(Handler.java:725)
12-30 15:55:33.377: I/dalvikvm(12862):   at android.os.Handler.dispatchMessage(Handler.java:92)
12-30 15:55:33.378: I/dalvikvm(12862):   at android.os.Looper.loop(Looper.java:153)
12-30 15:55:33.378: I/dalvikvm(12862):   at android.app.ActivityThread.main(ActivityThread.java:5297)
12-30 15:55:33.378: I/dalvikvm(12862):   at java.lang.reflect.Method.invokeNative(Native Method)
12-30 15:55:33.378: I/dalvikvm(12862):   at java.lang.reflect.Method.invoke(Method.java:511)
12-30 15:55:33.378: I/dalvikvm(12862):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
12-30 15:55:33.378: I/dalvikvm(12862):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
12-30 15:55:33.378: I/dalvikvm(12862):   at dalvik.system.NativeStart.main(Native Method)
12-30 15:55:33.379: E/dalvikvm(12862): VM aborting
12-30 15:55:33.380: A/libc(12862): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 12862 (.example.ledemo)

我不知道如何处理,我已经搜索了很多方法,但仍然找不到合适的方法。真的需要帮助。

【问题讨论】:

    标签: android c++ android-ndk java-native-interface


    【解决方案1】:

    你在这里所做的只是创建一个对加载的的全局引用:

    jclass clazz = env->FindClass("com/example/ledemo/MainActivity");
    
    gActivity = (jobject)env->NewGlobalRef(clazz);
    

    您没有创建该类的实例,这是setAppContext 所期望的。

    您对setJNI 的声明也有点不正确。而不是:

    extern "C" void  Java_com_example_ledemo_MainActivity_setJNI(
        JNIEnv* env,
        jclass clazz,
        jobject assetManager)
    

    应该是:

    extern "C" void  Java_com_example_ledemo_MainActivity_setJNI(
        JNIEnv* env,
        jobject thiz,   // <-- note the difference here
        jobject assetManager)
    

    jobject thiz 参数是对调用本机方法的 Java 对象的引用(即您的 MainActivity)。因此,您应该能够将 thiz 作为第二个参数传递给 setAppContext(我不确定您是否还需要创建对它的全局引用)。

    【讨论】:

    • 是的,你说得对。我使用了 jobject thiz 而不是 jclass clazz,但是由于添加了 jobect assetManager,logcat 会显示找不到方法的错误。所以我只是这样做Android ndk : Problem for call of Java method from c++ with jni
    • 我的主要问题是使用void setAppContext (::JavaVM &amp;,::jobject activity,::jobject assetManager);所以我应该放正确的参数来避免像 VM aborting 这样的错误
    • 好吧,在您展示的 Java 代码中,setJNI 是非静态的,因此第二个参数应该是 jobject 而不是 jclass。很难说为什么在没有看到错误消息的情况下会给你一个错误。
    • 我按你说的试试。 extern "C" void Java_com_example_ledemo_MainActivity_setJNI(JNIEnv* env, jobject obj, jobject assetManager) { using namespace LE; LE::Utility::setAppContext(*g_VM, gActivity, assetManager); LOGI("setContext finish"); } 但错误仍然显示 VM 正在中止,>12-30 18:01:04.882: W/dalvikvm(18671): JNI 警告: JNI 方法调用异常挂起>12-30 18:01:04.882: W/dalvikvm( 18671): 在 Lcom/example/ledemo/MainActivity;.setJNI:(Landroid/content/res/AssetManager;)V (CallObjectMethodV)`
    • 就像我在回答中写的那样,您不应该将 gActivity 传递给 setAppContext,因为这不是对 Activity 对象的引用 - 它是对您的 MainActivity 的引用 。将thiz 传递给setAppContext
    猜你喜欢
    • 1970-01-01
    • 2012-06-02
    • 1970-01-01
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    • 2015-07-01
    • 1970-01-01
    相关资源
    最近更新 更多