JDK-6539718 : Delphi-hosted JNI app fails when upgrading JRE/JDK from 1.5.0_11 to 1.6.0
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-03-28
  • Updated: 2011-02-16
  • Resolved: 2007-08-22
Description
FULL PRODUCT VERSION :
Version 1.6.0

FULL OS VERSION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
A Delphi app invokes a Java .class file, employing it as a Java "plug-in" module to customize a Windows native software program.  The Delphi app invokes a C++ DLL, which in turn invokes the Java module through the JNI using the C++ JNI support library for C++.

The native app activates the JVM, creates a Java object, and passes one double value to a Java object method to intialize, and then it repeatedly calls another method on that same object to pass an array of float values as input and to return an array of float values as output.  The program fails on the third invocation of that method that  receives and returns arrays of floats.

A simple Delphi test app that invokes the DLL and in turn invokes the Java module fails repeatedly in the same way.  A C++ test app that invokes the DLL that in turn invokes the Java module does not fail.

This failure is unique to Java 1.6.0 and does not occur under all versions tested of Java 1.5 and Java 1.4.  The application does not fail when run with -Xcheck:jni, but reports a warning message.  The warning

Java HotSpot(TM) Client VM warning: Floating point control word changed by native JNI code.

is issued by the call to CreateJavaVM.

  Bug ID 6346124 talks about issues with native programs that set the FPU control word  while Bug ID 4644270 talks about a divide-by-zero exception that is ignored in Java but propagates to Delphi.

The reported concern appears to be Delphi-specific, and it involves calling from Delphi down into Java, even if the JNI calls are made in a C++ module built with Microsoft compilers, and these other reports appear to assign blame to Delphi for assigning the FPU control word to get different floating point exception behavior than the JVM standard, but the problem I am reporting is new to Java 1.6 and was never an issue with Java 1.4 or 1.5.

What was changed in Java 1.6, and does that change improve performance or have other benefits that merit implementing a work-around on the Delphi side?  If this issue does not have a simple or desirable resolution on the JVM side, what information can you disclose to Delphi developers to warn them about using Delphi as part of JNI application bundles and proper handling of the FPU status?

Other bug reports talk about Java calling a Delphi native DLL and recommend saving and restoring the FPU control word before such a call.  This is the inverse situation of Delphi calling down to Java by invoking Java object method calls through the JNI as well as making multiple calls to the JNI library -- which calls need to be protected or guarded against FPU status word changes, and to what value does one need to set the FPU status word before calling into the JVM?

About the following question about the -server flag, CreateJavaVM reported that  "-server" is not a recognized option.


THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No

THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Did not try

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Invoking the test program JNITestD demonstrates the crash (source code follows).

EXPECTED VERSUS ACTUAL BEHAVIOR :
The program JNITestD produces the following output under Java 1.5.0_11:

CreateJavaVM
CreateJavaVM done
setMsFilter
setMsFilter done
block 0  avg 1.99872  count 4086
block 1  avg 2  count 4096
block 2  avg 2  count 4096
block 3  avg 2  count 4096
block 4  avg 2  count 4096
block 5  avg 2  count 4096
block 6  avg 2  count 4096
block 7  avg 2  count 4096
block 8  avg 2  count 4096
block 9  avg 2  count 4096
block 10  avg 2  count 4096
block 11  avg 2  count 4096
block 12  avg 2  count 4096
block 13  avg 2  count 4096
block 14  avg 2  count 4096
block 15  avg 2  count 4096
block 16  avg 2  count 4096
block 17  avg 2  count 4096
block 18  avg 2  count 4096
block 19  avg 2  count 4096

The following output is under Java 1.6.0

CreateJavaVM
CreateJavaVM done
setMsFilter
setMsFilter done
block 0  avg 1.99872  count 4086
block 1  avg 2  count 4096
#
# An unexpected error has been detected by Java Runtime Environment:
#
#  EXCEPTION_FLT_STACK_CHECK (0xc0000092) at pc=0x0094d069, pid=272, tid=224
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0-b105 mixed mode, sharing)
# Problematic frame:
# v  ~RuntimeStub::resolve_virtual_call
#
# An error report file with more information is saved as hs_err_pid272.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

As you see, the program fails when it attempts to process the third block of data (first two blocks reports success).

When the Delphi-Java bridge module JNIFilt.dll is recompiled to set the -Xcheck:jni option

-Xcheck:jni
CreateJavaVM
Java HotSpot(TM) Client VM warning: Floating point control word changed by native JNI code.
CreateJavaVM done
setMsFilter
setMsFilter done
block 0  avg 1.99872  count 4086
block 1  avg 2  count 4096
block 2  avg 2  count 4096
block 3  avg 2  count 4096
block 4  avg 2  count 4096
block 5  avg 2  count 4096
block 6  avg 2  count 4096
block 7  avg 2  count 4096
block 8  avg 2  count 4096
block 9  avg 2  count 4096
block 10  avg 2  count 4096
block 11  avg 2  count 4096
block 12  avg 2  count 4096
block 13  avg 2  count 4096
block 14  avg 2  count 4096
block 15  avg 2  count 4096
block 16  avg 2  count 4096
block 17  avg 2  count 4096
block 18  avg 2  count 4096
block 19  avg 2  count 4096

One sees that the program runs successfully, but check:jni gave a warning message at the CreateJavaVM call.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Attached seperatly

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
The test case requires 3 programs -- a Delphi main program, a C++ JNI bridge, and Java classes.  This is a simplified test case, and since it is JNI, and since I am using C++ as a bridge because I do not have a Delphi JNI library, all three are required. (Attached seperatly)

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Run with -Xcheck:jni and ignore the warning message.

Comments
WORK AROUND Try to add "-XX:+RestoreMXCSROnJNICalls" to avoid the crash you saw.
17-07-2007

EVALUATION Please confirm the comments made in the "Suggested Fix". Will close this CR within 2 weeks.
17-07-2007

SUGGESTED FIX Please try to add "-XX:+RestoreMXCSROnJNICalls" to avoid the crash you saw.
17-07-2007

EVALUATION Please try to add "-XX:+RestoreMXCSROnJNICalls" to see if you still see the same crash. Mark "incomplete" now.
30-06-2007