简体   繁体   English

C++ 到 JNI SIGSEGV 崩溃

[英]C++ to JNI SIGSEGV crash

I am slowly losing my mind as despite many attempts and searches I cannot find a viable solution to this.我正在慢慢失去理智,因为尽管进行了多次尝试和搜索,但我找不到可行的解决方案。

I get a crash when I am calling java / JNI from C++ using a string.当我使用字符串从 C++ 调用 java/JNI 时发生崩溃。

Any help would be much appreciated.任何帮助将非常感激。 I am new to JNI so I might do something wrong, aka should I preallocate memory buffer and pass that?我是 JNI 的新手,所以我可能做错了什么,也就是我应该预先分配内存缓冲区并传递它吗?

Code below下面的代码

Java bit Java位

public class helloWorld{
    public static void main(String[] args){
        System.out.println("Hello, World");
    }
    public static int square(int input){
        int output = input * input;
        return output;
    }
    public static int power(int input, int exponent){
        int output,i;
        output=1;
        for(i=0;i<exponent;i++){
            output *= input;
        }
        return output;
    }

    public static void hello(String val) {
    }
}

C++ bit C++位

#include <stdio.h>
#include <string>
#include <jni.h>
#include <iostream>


JNIEXPORT jstring JNICALL Java_com_baeldung_jni_HelloWorldJNI_sayHello (JNIEnv* env) {
    std::string hello = "Hello from C++ !!";
    std::cout << hello << std::endl;
    return env->NewStringUTF(hello.c_str());
}

JNIEnv* create_vm(JavaVM **jvm)
{
    JNIEnv* env;
    JavaVMInitArgs args;
    JavaVMOption options;
    args.version = JNI_VERSION_1_6;
    args.nOptions = 1;
    options.optionString = (char *)"-Djava.class.path=./";
    args.options = &options;
    args.ignoreUnrecognized = 0;
    int rv = JNI_CreateJavaVM(jvm, (void**)&env, &args);
    if (rv < 0 || !env)
        printf("Unable to Launch JVM %d\n",rv);
    else
        printf("Launched JVM! :)\n");
    return env;
}

void invoke_class(JNIEnv* env)
{
    jclass hello_world_class;
    jmethodID main_method;
    jmethodID square_method;
    jmethodID power_method;
    jint number=20;
    jint exponent=3;
    hello_world_class = env->FindClass("helloWorld");
    main_method = env->GetStaticMethodID(hello_world_class, "main", "([Ljava/lang/String;)V");
    square_method = env->GetStaticMethodID(hello_world_class, "square", "(I)I");
    power_method = env->GetStaticMethodID(hello_world_class, "power", "(II)I");
    env->CallStaticVoidMethod(hello_world_class, main_method, NULL);
    printf("%d squared is %d\n", number,
        env->CallStaticIntMethod(hello_world_class, square_method, number));
    printf("%d raised to the %d power is %d\n", number, exponent,
        env->CallStaticIntMethod(hello_world_class, power_method, number, exponent));
    printf("lalalalala\n");

    
    std::string message = "This comes from jni.";
    const char *result = message.c_str();
    jstring argString = env->NewStringUTF(result);
    

    jmethodID hello_method = env->GetStaticMethodID(hello_world_class, "hello", "([Ljava/lang/String;)V");
    env->CallStaticVoidMethod(hello_world_class, hello_method, argString);
}


int main(int argc, char **argv)
{
    JavaVM *jvm;
    JNIEnv *env;
    env = create_vm(&jvm);
    if(env == NULL)
        return 1;
    invoke_class(env);

    return 0;
}

and finally the log (truncated it as it was too long)最后是日志(因为太长而被截断了)

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x0000000105b76b9c, pid=94283, tid=259
#
# JRE version: OpenJDK Runtime Environment (16.0.1+9) (build 16.0.1+9-24)
# Java VM: OpenJDK 64-Bit Server VM (16.0.1+9-24, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, bsd-amd64)
# Problematic frame:
# V  [libjvm.dylib+0x571b9c]  jni_CallStaticVoidMethodV+0xcc
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# If you would like to submit a bug report, please visit:
#   https://bugreport.java.com/bugreport/crash.jsp
#

---------------  S U M M A R Y ------------

Command Line: 

Host: MacBookPro16,1 x86_64 2300 MHz, 16 cores, 16G, Darwin 20.4.0, macOS 11.3.1 (20E241)
Time: Fri Oct 15 13:38:03 2021 BST elapsed time: 0.115419 seconds (0d 0h 0m 0s)

---------------  T H R E A D  ---------------

Current thread (0x00007fc796008a00):  JavaThread "main" [_thread_in_vm, id=259, stack(0x00007ffee9e0b000,0x00007ffeea60b000)]

Stack: [0x00007ffee9e0b000,0x00007ffeea60b000],  sp=0x00007ffeea60a270,  free space=8188k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.dylib+0x571b9c]  jni_CallStaticVoidMethodV+0xcc
C  [a.out+0x3701]  JNIEnv_::CallStaticVoidMethod(_jclass*, _jmethodID*, ...)+0x171
C  [a.out+0x39df]  main+0xff
C  [libdyld.dylib+0x15f3d]  start+0x1


siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x0000000000000000

Register to memory mapping:

RAX=0x9d0fb75d63f100d0 is an unknown value
RBX=0x00007fc793f05418 points into unknown readable memory: 0x000000070fe19bc8 | c8 9b e1 0f 07 00 00 00
RCX=0x00007fc793f04ad8 points into unknown readable memory: 0x000000070fe1a1a8 | a8 a1 e1 0f 07 00 00 00
RDX=0x0 is NULL
RSP=0x00007ffeea60a270 is pointing into the stack for thread: 0x00007fc796008a00
RBP=0x00007ffeea60a310 is pointing into the stack for thread: 0x00007fc796008a00
RSI=0x00007fc793f05418 points into unknown readable memory: 0x000000070fe19bc8 | c8 9b e1 0f 07 00 00 00
RDI=0x00007fc796008d10 points into unknown readable memory: 0x0000000106275e58 | 58 5e 27 06 01 00 00 00
R8 =0x0 is NULL
R9 =0x0 is NULL
R10=0x00007fff20269e10: __vfprintf.xdigs_lower+0 in /usr/lib/system/libsystem_c.dylib at 0x00007fff201e7000
R11=0xffffffc8ab1fff06 is an unknown value
R12=0x00007fc796008a00 is a thread
R13=0x00007fc796008d10 points into unknown readable memory: 0x0000000106275e58 | 58 5e 27 06 01 00 00 00
R14=0x0 is NULL
R15=0x00007ffeea60a4a0 is pointing into the stack for thread: 0x00007fc796008a00

I answer my own question.我回答我自己的问题。 The problem was in the method signature passed to JNI with an extra [问题在于传递给 JNI 的方法签名带有额外的 [

jmethodID hello_method = env->GetStaticMethodID(hello_world_class, "hello", "([Ljava/lang/String;)V");
 jmethodID hello_method = env->GetStaticMethodID(hello_world_class, "hello", "(Ljava/lang/String;)V");

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

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