【问题标题】:JNI with native method malloc() causing crash on Cygwin带有本机方法 malloc() 的 JNI 在 Cygwin 上导致崩溃
【发布时间】:2015-04-20 21:19:59
【问题描述】:

我有一个用 C 语言编写的自定义 DLL,其中一个本机函数就这么简单:

void Java_main_Main_testMalloc(JNIEnv *env){
    char *c = malloc(sizeof(char)*5);
}

Java 内部:

package main;

public class Main {

    public static void main(String[] args){

        System.loadLibrary("libJNI_test1");
        Main m = new Main();
    }

    public Main(){
        testMalloc();
    }

    native void testMalloc();
}


Main:
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000018011ae47, pid=8604, tid=5464
#
# JRE version: Java(TM) SE Runtime Environment (8.0_05-b13) (build 1.8.0_05-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.5-b02 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [cygwin1.dll+0xdae47]

当然,这是精简版。但我确信由于我所做的所有测试,它会在 malloc() 上崩溃。只需注释掉malloc,编译DLL就可以了。崩溃并出现致命错误:EXCEPTION_ACCESS_VIOLATION (0xc0000005)。有时它运行良好,有时它会挂在 Java 调用本机方法的地方......我做错了什么?如何分配将临时用作缓冲区或 w/e 的本机内存?

【问题讨论】:

  • 这不是javah 生成的确切方法调用,是吗?你也应该有一个 jobject 传递。
  • @AndrewHenle,是的,根据 JNI,我必须默认拥有 JNIEnv 和 jobject。无论如何,问题仍然存在。我尝试用 c++ 编译器做同样的事情,只是将 malloc() 替换为 new char[5] 。而且它有效,完全没有问题。
  • 所以你没有正确定义你的方法,你想知道为什么它不能正常工作?
  • @AndrewHenle ,也许我没有澄清。无论我如何定义方法 - 有或没有 jobject - 它都不起作用 - 效果仍然相同。这是 malloc() 的错,因为当我切换到 c++ 并且一切都一样,但是将 malloc() 更改为 new char[5] 时,它可以完美地工作。但我需要在 C 领域。

标签: java c java-native-interface cygwin malloc


【解决方案1】:

JNI 声明必须完全具有正确的参数,包括未使用的参数,并且函数声明必须包括来自 jni.h 的宏 JNIEXPORT 和 JNICALL。如果没有这些,函数在退出时可能不会将堆栈返回到正确的状态,从而导致未定义的行为。

将函数声明改为:

 JNIEXPORT void JNICALL Java_main_Main_testMalloc(JNIEnv *env, jobject obj){
     char *c = malloc(sizeof(char)*5);
 }

然后看看你得到了什么。

【讨论】:

  • 同样的效果。编辑 OP 以包含一些细节。
  • 你能调用C库中的其他函数吗?
  • 尝试了一些任意的:rand() 有效,printf() 无效,strtod() 无效,sin() 有效,calloc() 无效,fopen() 无效。 :(
  • 有趣。如果这不是调用约定的问题(因为 JNICALL 等没有帮助),那么这一定是您的 cygwin 安装的问题。你必须使用cygwin吗?我遇到了各种各样的麻烦,可以建议 mingw 作为替代方案。
  • 很公平,我会在发布错误报告后尝试使用 mingw。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多