简体   繁体   中英

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 (ie 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?

你是不是错过了ReturnPacketBuffer = (*env)->NewCharArray(env, 64);

异常代码用于未经初始化的内存访问,作为提示,查找超出范围的索引。

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM