United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4976333 : Same jni code causes jvm to crash after upgrading from 141 to 142_03

Details
Type:
Bug
Submit Date:
2004-01-09
Status:
Closed
Updated Date:
2012-10-08
Project Name:
JDK
Resolved Date:
2004-03-30
Component:
hotspot
OS:
solaris_8,linux_redhat_2.1,windows_2000
Sub-Component:
runtime
CPU:
x86,sparc
Priority:
P1
Resolution:
Fixed
Affected Versions:
1.4.2_03
Fixed Versions:
1.4.2_05 (05)

Related Reports
Backport:

Sub Tasks

Description
My ISV is experiencing JNI problem - JVM crash with signal SIGABRT - after
upgrading from jre141_03 to jre142_03 with no code changes. Currently I don't have a testcase, but please look at the following pseudo code and shed some light on the questions. Your help is highly appreciated. BTW, the problem happens on multiple platforms: Solaris8, Windows2000, and RHAS2.1.

Basically, the overall architecture is:


UQSRV(c++) <-> JavaMessageServer(java) <-> dispatcher(c++)


In the above diagram, UQSRV is a server process written in c++. When a message event comes in, UQSRV passes the event to JavaMessageServer through JNI invocation(i.e. JNI_CreateJavaVM). JavaMessageServer then creates a java object KNEvent(pure java). After that, it calls dispatcher(native method defined in JavaMessageServer and implemented in c++) to dispatch it. The pseudo code is:

// create jvm instance in UQSRV through invocation
// vm flags are -verbose:jni -Xcheck:jni and the flags are for debug purpose
// vm will crash even without these flags
//

...
JNI_CreateJavaVM(&jvm, (void **) &env, &vm_args);
...

// then eventually it goes to dispatch native method 
void dispatch(JNIEnv *env, jobject object) {
  // get a globalref of object
  gJObject=env->NewGlobalRef(object);
  // delete the old one
  env->DeleteLocalRef(object);
}


In jre141, the same code runs fine; while in jre142, it's dumping core and the core file shows jvm is crashing at env->DeleteLocalRef() in method dispatch.
Error message from -verbose:jni -Xcheck:jni seems to confirm that:


FATAL ERROR in native method: Invalid local JNI handle passed to
DeleteLocalRef


Therefore, the ISV has the following questions/comments:
1. Is the above code correct? In JNI spec1.1, DeleteLocalRef() is applicable to local reference and passed-in argument seems to be viewed as local reference too(pass by reference for java object). So, could someone confirm that DeleteLocalRef() can be applied to a passed in java object?

2. If DeleteLocalRef() cannot be applied to passed-in java object(such as a spec change between minor releases?), why jre141 runs fine? 

3. If DeleteLocalRef() can be applied to passed-in java object as in jre141, it then is a bug(or regression) in jre142.

4. To further confirm the problem is from DeleteLocalRef(), I comment out the line which has DeleteLocalRef() and everything works fine afterwards. To use it as a workaround, the ISV would like to know whether commenting out DeleteLocalRef() will introduce memory leak. 

                                    

Comments
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
1.4.2_05
generic
tiger-beta2

FIXED IN:
1.4.2_05
tiger-beta2

INTEGRATED IN:
1.4.2_05
tiger-b51


                                     
2004-06-14
WORK AROUND

Commenting out env->DeleteLocalRef is NOT acceptable for the ISV, not only because it has not been stree tested, but also because it involves huge patch update work.
                                     
2004-06-11
SUGGESTED FIX

------- jniCheck.cpp -------
*** /tmp/sccs.msaiOo    Thu Jan 15 14:56:37 2004
--- jniCheck.cpp        Tue Jan 13 16:37:12 2004
***************
*** 563,569 ****
      functionEnter(thr);
      IN_VM(
        ValidateObject(thr, obj);
!       if (obj && !JNIHandles::is_local_handle(thr, obj))
          ReportJNIFatalError(thr,
              "Invalid local JNI handle passed to DeleteLocalRef");
      )
--- 563,569 ----
      functionEnter(thr);
      IN_VM(
        ValidateObject(thr, obj);
!       if (obj && !(JNIHandles::is_local_handle(thr, obj) || is_frame_handle(thr, obj)))
          ReportJNIFatalError(thr,
              "Invalid local JNI handle passed to DeleteLocalRef");
      )

###@###.### 2004-01-15
                                     
2004-01-15
EVALUATION

After further investigation, the customer actually put the check:jni flag in their native code. After remove the flag, the application does not crash. So the crash only happens with the fatalerror code in check:jni.

The fatalerror code reached because that in check deleteLocalRef(), it does not check if the local handle is frame handle after 1.4.2. I think it is probably intentionally removed because deleteLocalRef() for frame handle is not needed.

###@###.### 2004-01-13
                                     
2004-01-13



Hardware and Software, Engineered to Work Together