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?
User contributions licensed under CC BY-SA 3.0