Ben
Ben

Reputation: 1142

EXCEPTION_ACCESS_VIOLATION (0xc0000005) JVM from JNI?

I wrote some native methods in a vc++ with JNI to be accessed from java. Two of my three methods work perfectly fine with no issues. My last method, however, has been causing the following error message when i call it during runtime:

# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x61e06550, pid=3408, tid=4796
#
# JRE version: 7.0-b147
# Java VM: Java HotSpot(TM) Client VM (21.0-b17 mixed mode, sharing windows-x86 )
# Problematic frame:
# V  [jvm.dll+0xa6550]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows

Here is my native method's code (in vc++):

JNIEXPORT jcharArray JNICALL Java_jniusb_Main_receiveData (JNIEnv *env, jclass, jchar dataIndex)
{
    DWORD BytesWritten = 0;
    DWORD BytesRead = 0;
    unsigned char OutputPacketBuffer[65];   
    unsigned char InputPacketBuffer[65];    

    static jcharArray ReturnPacketBuffer;
    jchar temp[65];

    //send 'receive data' command to the firmware (OutputPacketBuffer[1])
    WriteFile(WriteHandle, &OutputPacketBuffer, 65, &BytesWritten, 0);
        //retrieve data from firmware
    ReadFile(ReadHandle, &InputPacketBuffer, 65, &BytesRead, 0);        

        for(int i=0;i<64;i++) 
    {
        temp[i] = jchar(InputPacketBuffer[i+1]);
    }

    (*env).SetCharArrayRegion(ReturnPacketBuffer, 0, 64, temp);
    return ReturnPacketBuffer;
}

My Java code looks like this (abridged of course):

public static native char[] receiveData(char dataIndex);

public static void main(String[] args) {
    char vid = 0x4d8;
    char pid = 0x3f;

    //check if read/write handles were retrieved 
    if(connectHid(vid, pid) == true)
    {
        System.out.println("connected!!!");
    }
    else
    {
        System.out.println("not connected...");
    }


    char[] test = new char[64];
    char[] receivetest = new char[64];

    char length = 0x03;
    char dataIndex = 0x81;

    test[0] = 0x80;
    test[1] = 0x80;
    sendData(test, length);
    receivetest = receiveData(dataIndex);

Like I said before, the other methods (i.e. connect and senddata) work fine and but I get the error from the receiveData method. After some debugging I discovered that the error goes away when I comment out the line:

(*env).SetCharArrayRegion(ReturnPacketBuffer, 0, 64, temp);

in my native code (of course the data never gets returned in this case...). What am I doing wrong here?

Upvotes: 3

Views: 8858

Answers (3)

Mahesh
Mahesh

Reputation: 34625

for(int i=0;i<64;i++) 
{
    temp[i] = jchar(InputPacketBuffer[i+1]);
}

temp can hold 65 elements of type jchar. They initially hold some garbage values. With the above loop, you try to fill from 0 to 63 elements. The last element is left unfilled and is left with the garbage value which it had initially.

(*env).SetCharArrayRegion(ReturnPacketBuffer, 0, 64, temp);

Probably, the above statement is working on value at the 64th index of temp and is failing because of garbage in it. Try giving an index less than 64, it works, IMO. Or fill the 64th index also with a valid value by incrementing the for loop iteration to one another iteration.

Upvotes: 1

zeller
zeller

Reputation: 4974

The exception code is for uninitalized memory access, as a hint, look for indexing out of bounds.

Upvotes: 2

Ben van Gompel
Ben van Gompel

Reputation: 745

Aren't you missing something like ReturnPacketBuffer = (*env)->NewCharArray(env, 64);

Upvotes: 2

Related Questions