[Info-vax] JNI problem on I64
Arne Vajhøj
arne at vajhoej.dk
Wed Feb 2 19:03:59 EST 2022
On 1/25/2022 7:39 PM, Arne Vajhøj wrote:
> Code outline:
>
> ... (JNIEnv *cntx, jobject baobj)
> ...
> signed char *buf;
> ...
> buf = (*cntx)->GetByteArrayElements(cntx, baobj, NULL);
> ...
> ...
> ...
> (*cntx)->ReleaseByteArrayElements(cntx, baobj, buf, 0);
>
> VMS Alpha 8.4 with Java 1.5 : works fine
>
> VMS I64 8.4 with Java 8 : crashes (the output is attached below)
>
> ReleaseByteArrayElements calls memcpy and memcpy calls something
> in LIBOTS that does an access violation.
>
> I understand the memcpy - if GetByteArrayElements returned a copy
> of the JVM data then ReleaseByteArrayElements has to copy the modified
> data back.
>
> But neither baobj nor buf has changed. So I am totally baffled
> over why I can get an access violation.
>
> Does anyone have an idea about what I should be looking for?
> # A fatal error has been detected by the Java Runtime Environment:
> #
> # %SYSTEM-F-ACCVIO (0xc) at pc=84234440, pid=1064, tid=0x000000007b6ecec0
> Stack: [7AB16000,7AD16000], sp=7AD0FE10, free space=2023k
> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code,
> C=native code)
> C [LIBOTS+0x2c0] +0x84234440
> C [DECC$SHR+0x30] C$$MEMFUNC/_memcpy64+0x8484b5f0
> C [java$jvm_shr+0x320] jni/jni_ReleaseByteArrayElements+0xce6de0
> C [VMScall_shr+0x5300]
> dk_vajhoej_vms_call_vms/Java_dk_vajhoej_vms_call_VMS_callFunction+0x9b88e10
A followup.
Problems solved.
A gazillion printf statements printing out everything everywhere
revealed what was going on.
And as usual the problem was of course in my code.
I wrote that "neither baobj nor buf has changed" - and that is
true as none of the 4 (!!) pointers changed.
It turned out that GetByteArrayElements was called twice.
And there was a baobj pointing to the object containing
the byte array and a baobj pointing to the actual byte array.
typedef jobject jarray;
typedef jarray jbyteArray;
does that the compiler cannot see the difference between
jobject and jbyteArray.
But everything worked fine on Java 5 on VMS Alpha.
GetByteArrayElements returns a pointer to the original
so two calls to GetByteArrayElements is not a problem
as they return the same pointer.
ReleaseByteArrayElements does not need to copy anything,
back so it does not need the argument.
Just for fun I tried:
(*cntx)->ReleaseByteArrayElements(cntx, NULL, NULL, 0);
no exceptions!
But Java 8 on VMS I64 is a different story. GetByteArrayElements
return a copy.
The two calls to GetByteArrayElements returned different
pointers.
ReleaseByteArrayElements actually need to copy back so
it took the pointer to the wrong type and just used
it as if the right type. And the memcpy bombed.
So time to clean up the code.
Only call GetByteArrayElements once.
And call ReleaseByteArrayElements with the right pointer
everywhere.
Now it woks.
Arne
More information about the Info-vax
mailing list