0

I'm trying to connect my Java code with a C program (translated using GnuCobol) using JNI. Unfortunately, I can't access the C source code and rewrite in Java, so I've created a wrapper C program to call it.

Help with the following ERROR

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

The error occurs on the second attempt to get some response from the C program.

Log generated using -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

And I need help to figure out the cause of this.

Sources

The java snippet

    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);
    }

The gnucobollib main C source

#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);

}

The method CALLBANANA is from a translated Cobol code using GNUCobol.

Temporary Solution

Handle all signals direct on C wrapper program. Despite of the error message, everything works fine and million of calls to GnuCobol happened without any issue.

Still pending the recompile of the code to latest version of GnuCobol

Lucas Licursi
  • 42
  • 1
  • 8
  • On the face of it, the JVM tells you that your function writes to more than 16162 bytes of bufferResponse. If this size should be `sizeof(struct utm2)`, the reason could be that you did not take alignment into account. But these are speculations. You should step through this wrapper in debugger, or add log prints. – Alex Cohn Jan 19 '18 at 05:21
  • 2
    The overrun appears to be detected when `ReleasePrimitiveArrayCritical` is called. Where does this call come from? The function you've shown us only calls `ReleaseByteArrayElements`. Also, the size of the buffer in question appears to be 324 bytes. What buffers do you have that match that size? – Michael Jan 19 '18 at 11:26
  • @AlexCohn Thanks for the suggestion, changed to 16164, but didn't work. – Lucas Licursi Jan 20 '18 at 09:39
  • @Michael, the buffer in question does not have explicit relation with request or response, because even changing both sizes to higher or lower values it resulted in the same error message. – Lucas Licursi Jan 20 '18 at 09:39
  • @Michael, good catch about the size, my count gives 356 though. At any rate, the crash does look unrelated to `struct utm2`, and most likely not coming from **CALLBANANA** – Alex Cohn Jan 20 '18 at 14:36
  • 1
    @AlexCohn: The extra 32 bytes are made up of the header/trailer guard data, the size value, and a tag. – Michael Jan 20 '18 at 14:43
  • Just some notes: If you always start with `CALLBANANA` then you can drop your manual initialization and just compile the program with `-fimplicit-init` (for completeness it would be good to specify which `cobc` options are used to compile the program and ideally add a test program (just containing the `LINKAGE`, do a `DISPLAY` of the bufferRequest and `MOVE` to bufferResponse) that produces the error, too. – Simon Sobisch Jan 23 '18 at 08:31
  • Thanks for the advice @SimonSobisch. I will take me a few days to recompile it with the latest gnucobol, since I don't have the source. – Lucas Licursi Jan 23 '18 at 10:19

0 Answers0