我正在尝试使用 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);
}
主要的gnucobollib
C 源代码
#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