0

我正在尝试使用 JNI 将我的 Java 代码与 C 程序(使用 GnuCobol 翻译)连接起来。不幸的是,我无法访问 C 源代码并用 Java 重写,所以我创建了一个包装 C 程序来调用它。

帮助解决以下错误

ProgramX.cbl:112: Attempt to reference unallocated memory (Signal SIGSEGV)

该错误发生在第二次尝试从 C 程序获得一些响应时。

使用 -Xcheck:jni 生成的日志

ReleasePrimitiveArrayCritical: release array failed bounds check, incorrect pointer returned ? array: 0x00007fd10a6514c0 carray: 0x00007fd104a93400
GuardedMemory(0x00007fd10a651330) base_addr=0x00007fd104a933e0 tag=0x00007fd104a93290 user_size=324 user_data=0x00007fd104a93400
  Header guard @0x00007fd104a933e0 is OK
  Trailer guard @0x00007fd104a93544 is BROKEN
  User data appears to be in use
FATAL ERROR in native method: ReleasePrimitiveArrayCritical: failed bounds check

我需要帮助找出原因。

来源

Java 代码片段

    static {
        System.loadLibrary("gnucobollib");
    }

    public native void callGnuCobol(byte[] request, byte[] response);

    private void invokeNativeCall(AbstractData... args) {
        // Changed size from 16162 to the correct size 16164 
        // as suggested in comment by Alex Cohn
        byte[] responseBytes = new byte[16164];
        String request = "Personal sensitive data";
        callGnuCobol(utm1.getBytes(), responseBytes);
        String resonse = new String(responseBytes);
    }

主要的gnucobollibC 源代码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cpy/utm1.h"
#include "cpy/utm2.h"
#include "jni/testJavaJni.h"

static int cobc_runtime_initialized = 0;

static void init_cobc_runtime() {
    if (!cobc_runtime_initialized) {
        printf("initializing cobc runtime\n");
        cob_init(0, NULL);
        cobc_runtime_initialized = 1;
    }
}

JNIEXPORT void JNICALL Java_com_att_ub_ub2l_cbct545_Cbct545Program_callGnuCobol(JNIEnv *env, jobject thisObj, jbyteArray request,  jbyteArray response)
{
    init_cobc_runtime();
    jbyte* bufferRequest = (*env)->GetByteArrayElements(env, request, NULL);
    jbyte* bufferResponse = (*env)->GetByteArrayElements(env, response, NULL);

    CALLBANANA((struct utm1*)&bufferRequest[0], (struct utm2*)&bufferResponse[0]);

    (*env)->ReleaseByteArrayElements(env, request, bufferRequest, 0);
    (*env)->ReleaseByteArrayElements(env, response, bufferResponse, 0);

}

该方法CALLBANANA来自使用 GNUCobol 翻译的 Cobol 代码。

临时解决方案

直接在 C 包装程序上处理所有信号。尽管有错误消息,但一切正常,对 GnuCobol 的数百万次调用没有任何问题。

仍在等待将代码重新编译为最新版本的 GnuCobol

4

0 回答 0