g++ 编译后的核心转储 + 与 jni 的链接以及随后使用 C++ 和 Java 执行应用程序

Posted

技术标签:

【中文标题】g++ 编译后的核心转储 + 与 jni 的链接以及随后使用 C++ 和 Java 执行应用程序【英文标题】:Core dump following g++ compilation + link with jni and subsequent execution of application using C++ and Java 【发布时间】:2012-12-13 23:37:18 【问题描述】:

我需要在 C++ 中执行一些任意 Java 代码。我正在为此使用 JNI,但遇到了一个问题。 C++ 文件可以正常编译,但是在执行时会生成以下内容:

Java 运行时环境检测到致命错误:

SIGSEGV (0xb) 在 pc=0xb6f90ffb,pid=10063,tid=3062122240

JRE 版本:7.0_10-b18 Java 虚拟机:Java HotSpot(TM) 服务器虚拟机(23.6-b04 混合模式 linux-x86) 有问题的框架: V [libjvm.so+0x440ffb] JNI_ArgumentPusherVaArg::JNI_ArgumentPusherVaArg(_jmethodID*, char*)+0x1b

已写入核心转储。默认位置:/home/alex/candjava/core 或 core.10063

包含更多信息的错误报告文件保存为: /home/alex/candjava/hs_err_pid10063.log

如果您想提交错误报告,请访问: http://bugreport.sun.com/bugreport/crash.jsp

中止(核心转储)

编译命令:

g++ sample.cpp -o app -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -I $JAVA_HOME/jre/lib/i386/client -L$JAVA_HOME/jre/lib/i386/client -ljvm -Wno-write-strings

其中$JAVA_HOME/usr/lib/jvm/java-7-oracle

java源码:

public class Main

public void test()
    System.out.println("HELLO WORLD");
    

C++ 源代码:

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

int main()

    JavaVM *jvm;       /* denotes a Java VM */
    JNIEnv *env;       /* pointer to native method interface */
    JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */
    JavaVMOption* options = new JavaVMOption[1];
    options[0].optionString = "-D java.class.path=/usr/lib/jvm/java-7-oracle/bin";
    vm_args.version = JNI_VERSION_1_6;
    vm_args.nOptions = 1;
    vm_args.options = options;
    vm_args.ignoreUnrecognized = false;
    /* load and initialize a Java VM, return a JNI interface
     * pointer in env */
    JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
    delete options;
    /* invoke the Main.test method using the JNI */
    jclass cls = env->FindClass("Main");
    jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V");
    env->CallStaticVoidMethod(cls, mid, 100);
    /* We are done. */
    jvm->DestroyJavaVM();


对此的任何帮助将不胜感激!

【问题讨论】:

这是一个非常奇怪的类路径。 这个选项里面不应该有空格,它应该指向一些Java类的位置"-D java.class.path=/usr/lib/jvm/java-7-oracle/bin" 【参考方案1】:

您没有检查来自 JNI 函数的任何错误返回。您需要检查错误。

【讨论】:

***.com/questions/7559059/… 我使用该链接中列出的代码来解决我的问题,谢谢【参考方案2】:
jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V");

说你的函数是无效的,你有整数作为参数。 但您没有发送任何整数参数 应该是这样的

jmethodID mid = env->GetStaticMethodID(cls, "test", "()V");

【讨论】:

【参考方案3】:

您的源代码中有一些明显的错误。

    Main 类中的测试方法应该是静态的 测试参数应该是int java.class.path 参数很可笑

我还有第三个问题。更改选项-Djava.class.path=/Path-to-your-class-file-directory 就可以了。 (我的是"-Djava.class.path=."

【讨论】:

以上是关于g++ 编译后的核心转储 + 与 jni 的链接以及随后使用 C++ 和 Java 执行应用程序的主要内容,如果未能解决你的问题,请参考以下文章

[c的JNI调用java导致分段错误(内核已转储)

使用带有自定义对齐分配器实现的最新 g++ 使用 SSE 和 -O3 选项编译时出现非法指令(核心转储)

如何调试从执行发布文件生成的核心转储文件?

分段故障核心转储错误

gcc地址清理程序核心转储出错

C中的另一个核心转储问题