You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JNI应用抛出NoSuchMethodError并触发SIGSEGV崩溃求助

JNI绑定调用时触发NoSuchMethodError与SIGSEGV崩溃

通过CMake构建C++实现JNI绑定,调用CimFileHelper.load方法时,JVM先抛出java/lang/NoSuchMethodError(提示找不到sun.misc.Unsafe.defineClass和prefetchRead方法),随后触发SIGSEGV崩溃,以下是相关代码与错误日志:

Java代码(含native方法)

public class CimFileHelper {
    static {
        System.loadLibrary("CimFileHelper");
    }

    public native CimElement[] load(String filePath) throws IOException;
}

C++核心实现代码

JNIEXPORT jobjectArray JNICALL Java_com_xxx_CimFileHelper_load
  (JNIEnv *env, jobject, jstring file_path) {
    // call load_cim_file
}

// load xml.
int load_cim_file(JNIEnv *env, const char* file_path, jobject (*cim_elem_list)[]) {
    // call load_elements
}

// load children elements.
int load_elements(JNIEnv *env, xml_node root, jobject (*list)[]) {
    int count = 0;
    for (xml_node node = root.first_child(); node; node=node.next_sibling()) {
        if (node.type() != node_element) continue;

        jobject cim_elem = load_element(env, node);
        (*list)[count++] = cim_elem;
        env->DeleteLocalRef(cim_elem);
        if (count>3) break; // make a short test.
    }

    return count;
}

// load each element
jobject load_element(JNIEnv *env, xml_node node) {
    jobject cim_elem = new_instance(env, CLS_NAME_CIM_ELEMENT);

    const char_t* node_tag_w = node.name();
    string node_tag = as_utf8(node_tag_w);
    set_str_value(env, cim_elem, CLS_NAME_CIM_ELEMENT, FIELD_NAME_CIM_ELEMENT_TYPE, node_tag.c_str());

    string text = get_element_text(node);
    if (!text.empty()) 
        set_str_value(env, cim_elem, CLS_NAME_CIM_ELEMENT, FIELD_NAME_CIM_ELEMENT_TEXT, text.c_str());

    return cim_elem;
}

// java new instance.
jobject new_instance(JNIEnv *env, const char* class_name) {
    jclass cls = find_class(env, class_name);

    jmethodID constructor = find_method(env, class_name, METHOD_NAME_CONSTRUCTOR, SIG_METHOD_EMPTY_VOID);
    if (!constructor) {
        cerr<<"Cannot find construtor for "<<class_name<<endl;
        throw ERR_METHOD_NOT_FOUND;
    }
    
    jobject obj = env->NewObjectA(cls, constructor, new jvalue[0]);

    return obj;
}

运行时错误日志

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f2f7339061f, pid=82817, tid=0x00007f2fc52ac700
#
# JRE version: OpenJDK Runtime Environment (8.0_352-b08) (build 1.8.0_352-352-b08)
# Java VM: OpenJDK 64-Bit Server VM (25.352-b08 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  [libCimFileHelper.so+0x4961f]  load_elements(JNIEnv_*, pugi::xml_node, _jobject* (*) [])+0x11f

...

Stack: [0x00007f2fc51ad000,0x00007f2fc52ad000],  sp=0x00007f2fc52ab670,  free space=1017k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [libCimFileHelper.so+0x4961f]  load_elements(JNIEnv_*, pugi::xml_node, _jobject* (*) [])+0x11f
C  [libCimFileHelper.so+0x4983c]  load_cim_file(JNIEnv_*, char const*, _jobject* (*) [])+0x1c2
C  [libCimFileHelper.so+0x1a982]  Java_com_xxx_CimFileHelper_load+0x4e
j  com.xxx.CimFileHelper.load(Ljava/lang/String;)[Lcom/xxx/CimElement;+0
j  com.xxx.CimFileHelperTest.main([Ljava/lang/String;)V+59
v  ~StubRoutines::call_stub
V  [libjvm.so+0x65600e]  JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0xf3e
V  [libjvm.so+0x6b750a]  jni_invoke_static(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*) [clone .isra.195]+0x30a
V  [libjvm.so+0x6c905e]  jni_CallStaticVoidMethod+0x16e
C  [libjli.so+0x82b9]  JavaMain+0xa09
C  [libpthread.so.0+0x8ea7]  start_thread+0xd7

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  com.xxx.CimFileHelper.load(Ljava/lang/String;)[Lcom/xxx/CimElement;+0
j  com.xxx.CimFileHelperTest.main([Ljava/lang/String;)V+59
v  ~StubRoutines::call_stub

...

Internal exceptions (6 events):
Event: 0.018 Thread 0x00007f2fc000a800 Exception <a 'java/lang/NoSuchMethodError': Method sun.misc.Unsafe.defineClass(Ljava/lang/String;[BII)Ljava/lang/Class; name or signature does not match> (0x000000076d307cd8) thrown at [/home/centos/8/hotspot/src/share/vm/prims/jni.cpp, line 4014]
Event: 0.018 Thread 0x00007f2fc000a800 Exception <a 'java/lang/NoSuchMethodError': Method sun.misc.Unsafe.prefetchRead(Ljava/lang/Object;J)V name or signature does not match> (0x000000076d307fc0) thrown at [/home/centos/8/hotspot/src/share/vm/prims/jni.cpp, line 4014]
Event: 1.439 Thread 0x00007f2f78001000 Exception <a 'java/security/PrivilegedActionException'> (0x000000076dd97d00) thrown at [/home/centos/8/hotspot/src/share/vm/prims/jvm.cpp, line 1514]
Event: 1.439 Thread 0x00007f2f78001000 Exception <a 'java/security/PrivilegedActionException'> (0x000000076dd980f8) thrown at [/home/centos/8/hotspot/src/share/vm/prims/jvm.cpp, line 1514]
Event: 1.440 Thread 0x00007f2f78001000 Exception <a 'java/security/PrivilegedActionException'> (0x000000076dd9af18) thrown at [/home/centos/8/hotspot/src/share/vm/prims/jvm.cpp, line 1514]
Event: 1.440 Thread 0x00007f2f78001000 Exception <a 'java/security/PrivilegedActionException'> (0x000000076dd9b310) thrown at [/home/centos/8/hotspot/src/share/vm/prims/jvm.cpp, line 1514]

...

排查与解决思路

1. 优先修复SIGSEGV崩溃

  • 非法内存访问定位:崩溃发生在load_elements函数中(*list)[count++] = cim_elem;行,需确认:
    • load_cim_file传入的cim_elem_list是否已分配足够内存,避免越界访问
    • 禁止使用未初始化或已释放的指针
  • 局部引用误用:代码中存入list后立即调用DeleteLocalRef,导致list中的引用失效,后续操作必然触发内存错误。需保留局部引用,直到将对象存入JNI数组或转为全局引用后再释放。

2. 处理NoSuchMethodError警告

  • Unsafe方法签名不匹配:OpenJDK 8中sun.misc.Unsafe.defineClass的正确签名包含ClassLoader和ProtectionDomain参数,错误日志中的签名缺失这些参数;prefetchRead签名也可能因JDK版本差异不匹配。
  • 定位触发源:检查代码或依赖库是否直接/间接调用了Unsafe的这些方法。如果是第三方库导致,升级库版本或替换为不依赖Unsafe的实现;如果是自有代码,修正方法签名以匹配当前JDK版本。

3. 规范JNI代码实现

  • NewObjectA优化:空参数场景下,直接使用env->NewObject(cls, constructor)更安全,避免不必要的内存分配
  • 类与方法校验:确认find_class和find_method的实现是否正确,比如类的全限定名、方法签名是否完全匹配(构造方法签名为()V)
  • 异常检查:JNI调用后需及时通过env->ExceptionCheck()检查异常,避免未处理异常导致后续代码执行错误

内容的提问来源于stack exchange,提问作者Joson_prog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 23:55:27