Access violation calling memcpy() inside JNI library doing USB i/o

0

I am writing a Java application that executes USB I/O on Windows 10 with Java 10 JDK. My i/o library is the libusb api. The app loads a JNI library .dll compiled/built in Visual Studio 2017 with both Microsoft Visual 2013 C++ and Microsoft Visual C++ 2015-2019 installed. This application generates the following crash warning when ran inside a Netbeans 11.1 project.

EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000002e1bbcd122e, pid=444, tid=3244
JRE version: Java(TM) SE Runtime Environment (10.0+46) (build 10+46) Java VM: Java HotSpot(TM) 64-Bit Server VM (10+46, mixed mode, tiered, compressed oops, g1 gc, windows-amd64)

Problematic frame:
C [VCRUNTIME140D.dll+0x122e]

The problem function is my USB read function within the C code in the VisualStudio-built .dll.

JNI.c

JNIEXPORT jint JNICALL Java_SWMAPI_IoUSB_read
(JNIEnv * env, jobject thisObj, jbyteArray jArr, jint size, jlong javaHandle){   

    //Convert jLong to device handle pointer
    libusb_device_handle * handle = (libusb_device_handle * )javaHandle;

    //jbyteArray jArr: byte [] buffer.  Must be overwritten with USB read data from device with 
    //                                  corresponding handle javaHandle.
    //jlong javaHandle:  long passed from java representing the device to I/O.
    //jint size:         jArr length (e.g. buffer.length), used for debugging.

    int status;         //return code value
    int bytes_written;
    int bytes_read;

    MESSAGE Message;    //C struct containing 9 bytes of message header and (n) bytes of payload.

    int length = (*env)->GetArrayLength(env, jArr);

    jbyte * bufferIn = (*env)->GetPrimitiveArrayCritical(env, jArr, NULL);  //get memory from jArr

    //copy data in bufferIn to a Message struct.
    memcpy((unsigned char *)&Message, (unsigned char *)bufferIn, length);  

    //write the Message out to device
    bytes_written = libusb_control_transfer(handle, CTRL_OUT, MEM_RQ, 0, 0, (unsigned char *)&Message, length, 0);

    if(bytes_written == length){
        //read data in from Device to &Message
        bytes_read = libusb_control_transfer(handle, CTRL_IN, MEM_RQ, 0, 0, (unsigned char 
        *)&Message, sizeof(MESSAGE), 30000);

        status = (bytes_written < 0) ? bytes_read :                 // I/O Error
            (bytes_written < length) ? USB_STATUS_SHORT_WRITE :     // Check for short write
            LIBUSB_SUCCESS;
        if(Message.payload.length >= 0){                            //If read data > 0
            printf("Attempting memcpy\n");
            fflush(stdout);

            // The error appears on the line below
            memcpy((unsigned char *)bufferIn,(unsigned char *)&Message, MAX_HEADER_LENGTH + 
            Message.payload.length);

            printf("Success memcpy\n");
            fflush(stdout);
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, jArr, bufferIn, 0);
    return status;
}

This function has been working for my project up until today. Its frequency is approx 1 out of 3 runs. Can anyone please advise me on how I can move forward to solving this issue?

java
c
java-native-interface
asked on Stack Overflow Mar 9, 2020 by idioteque90 • edited Mar 10, 2020 by Botje

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0