Open enasser opened 6 years ago
Additional experiment results as per @DanHeidinga suggestion:
A JNI native (not customer launcher) invoking feenableexcept()
before Java performing divided-by-zero produces following result against RI JDK8 (and JDK11):
Exception in thread "main" java.lang.ArithmeticException: / by zero
at ProgV2.main(ProgV2.java:11)
It looks like RI signal handlers catch the error and map it to an exception.
Java code snippets:
public static native void setfp();
static {
System.loadLibrary("ProgV2");
}
public static void main(String[] args) {
setfp();
double input = 00.0000;
System.out.println("Inverse of "+ input + " is " + 1/input);
}
Native code snippets:
JNIEXPORT void JNICALL Java_ProgV2_setfp(JNIEnv *env, jclass thisClz) {
feenableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW);
return;
}
@JasonFengJ9 That is an interesting observation. So with RI JDK, there is difference in behavior when the SIGFPE is enabled before and after create JVM. If the trap is enabled before create JVM, it just catch the exception and continue where as if the trap is enabled after create JVM, then it result in the ArithmeticException.
@enasser that's correct.
As per the JVM specification https://docs.oracle.com/javase/specs/jvms/se10/html/jvms-2.html#jvms-2.8.1, SIGFPE should be consumed by the JVM even if trap is enabled. Hotspot handles SIGFPE and provides Infinity for a divide-by-zero where as OpenJ9 crash.
Please find below the test case to recreate the issue: test_case.zip
Recreate step:
With Hotspot:
With J9: