RFR: JDK-8211161: java.lang.ArithmeticException: divide by zero from java.text.DecimalFormat.format()
Hello, In java.text.DecimalFormat.format(), there is a validation to check whether a number is negative zero or not and for that divide by zero is used to check for negative infinity which caused the ArithmeticException when SIGFPE is enabled in the system. Andrew has opened a bug on my behalf. Thank you Andrew. The corresponding bug is https://bugs.openjdk.java.net/browse/JDK-8211161. The webrev and stand alone test case is uploaded to http://cr.openjdk.java.net/~aleonard/8211161/. The recreate step is documented in the bug description. I have tested the fix with the test cases of the following bugs and confirm that it is working. https://bugs.java.com/view_bug.do?bug_id=4106658 https://bugs.java.com/view_bug.do?bug_id=4106667 https://bugs.java.com/view_bug.do?bug_id=4147706 I did not add any new jtreg test for the current issue as it is not functional. Hope that is fine. Kindly request you to review and comment. Thank you, Nasser Ebrahim
Hello, It may be reasonable to replace a divide by zero with check for a floating-point -0.0 with a bit-level check, but the stated motivation is not reasonable. The Java platform requires that floating-point divide by zero return an infinity (or NaN as the case may be) and it is *incorrect* and non-conformant to throw an ArithmeticException in that case. Such behavior violates the language the JVM specs. Cheers, -Joe On 9/26/2018 9:33 AM, Nasser Ebrahim wrote:
Hello,
In java.text.DecimalFormat.format(), there is a validation to check whether a number is negative zero or not and for that divide by zero is used to check for negative infinity which caused the ArithmeticException when SIGFPE is enabled in the system. Andrew has opened a bug on my behalf. Thank you Andrew.
The corresponding bug is https://bugs.openjdk.java.net/browse/JDK-8211161.
The webrev and stand alone test case is uploaded to http://cr.openjdk.java.net/~aleonard/8211161/. The recreate step is documented in the bug description.
I have tested the fix with the test cases of the following bugs and confirm that it is working. https://bugs.java.com/view_bug.do?bug_id=4106658 https://bugs.java.com/view_bug.do?bug_id=4106667 https://bugs.java.com/view_bug.do?bug_id=4147706
I did not add any new jtreg test for the current issue as it is not functional. Hope that is fine.
Kindly request you to review and comment.
Thank you, Nasser Ebrahim
Hi Joe, Thank you for your review comments. I agree with you that the specification says that "The floating-point operations of the Java Virtual Machine do not throw exceptions, trap, or otherwise signal the IEEE 754 exceptional conditions of invalid operation, division by zero, overflow, underflow, or inexact." as per the JVM specification https://docs.oracle.com/javase/specs/jvms/se10/html/jvms-2.html#jvms-2.8.1 . I noticed that the SIGFPE is consumed and no exception is thrown when SIGFPE is enabled before create JVM. Hence, there is an inconsistency in the hotspot 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. Hence, the JVM behavior needs to be fixed to make the behavior consistent. Still, I feel it makes more sense to check the sign bit to decide a number is negative or positive rather than divide-by-zro to make infinity and compare with zero. If you agree with my view, a separate bug can be opened to fix the JVM inconsistent behavior. Otherwise, we can change the component of this bug. Please comment. Thank you, Nasser Ebrahim From: joe darcy <joe.darcy@oracle.com> To: Nasser Ebrahim <enasser@in.ibm.com>, core-libs-dev Libs <core-libs-dev@openjdk.java.net> Date: 09/26/2018 10:29 PM Subject: Re: RFR: JDK-8211161: java.lang.ArithmeticException: divide by zero from java.text.DecimalFormat.format() Hello, It may be reasonable to replace a divide by zero with check for a floating-point -0.0 with a bit-level check, but the stated motivation is not reasonable. The Java platform requires that floating-point divide by zero return an infinity (or NaN as the case may be) and it is *incorrect* and non-conformant to throw an ArithmeticException in that case. Such behavior violates the language the JVM specs. Cheers, -Joe On 9/26/2018 9:33 AM, Nasser Ebrahim wrote:
Hello,
In java.text.DecimalFormat.format(), there is a validation to check whether a number is negative zero or not and for that divide by zero is used to check for negative infinity which caused the ArithmeticException when SIGFPE is enabled in the system. Andrew has opened a bug on my behalf. Thank you Andrew.
The corresponding bug is https://bugs.openjdk.java.net/browse/JDK-8211161 .
The webrev and stand alone test case is uploaded to
http://cr.openjdk.java.net/~aleonard/8211161/ .
The recreate step is documented in the bug description.
I have tested the fix with the test cases of the following bugs and confirm that it is working.
https://bugs.java.com/view_bug.do?bug_id=4106658
https://bugs.java.com/view_bug.do?bug_id=4106667
https://bugs.java.com/view_bug.do?bug_id=4147706
I did not add any new jtreg test for the current issue as it is not functional. Hope that is fine.
Kindly request you to review and comment.
Thank you, Nasser Ebrahim
Hi Nasser, On 9/26/2018 10:44 AM, Nasser Ebrahim wrote:
Hi Joe,
Thank you for your review comments.
I agree with you that the specification says that "The floating-point operations of the Java Virtual Machine do not throw exceptions, trap, or otherwise signal the IEEE 754 exceptional conditions of invalid operation, division by zero, overflow, underflow, or inexact." as per the JVM specification https://docs.oracle.com/javase/specs/jvms/se10/html/jvms-2.html#jvms-2.8.1.
I noticed that the SIGFPE is consumed and no exception is thrown when SIGFPE is enabled before create JVM. Hence, there is an inconsistency in the hotspot 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.Hence, the JVM behavior needs to be fixed to make the behavior consistent.
Still, I feel it makes more sense to check the sign bit to decide a number is negative or positive rather than divide-by-zro to make infinity and compare with zero. If you agree with my view, a separate bug can be opened to fix the JVM inconsistent behavior. Otherwise, we can change the component of this bug. Please comment.
Here is my rephrasing of the situation: If someone deliberately misconfigures a CPU such that its floating-point behavior does not conform to the JVM specification, Java library code throws unexpected exceptions. In that case, it is not a bug in the library code, it is a problem stemming from the deliberate CPU misconfiguration. One could make a case that the new code is better in some way, perhaps faster on some platforms, but it is functionally correct as is and should not be described otherwise. The i18n team can weigh in with their assessment of the proposed patch from a maintenance perspective. The HotSpot team could evaluate if the VM implementation should be further hardened against hostile changes to the FPU control word(s), but I would be content if this issue were closed as not a bug. Cheers, -Joe
Hi, Nasser, Joe, I agree with Joe as to the assessment on DecimalFormat code. The existing code looks correct. Unless there is any obvious need to replace the piece with bit operation, I'd just leave it as is. The jira issue can be transferred to HotSpot, though. Naoto On 9/26/18 11:14 AM, joe darcy wrote:
Hi Nasser,
On 9/26/2018 10:44 AM, Nasser Ebrahim wrote:
Hi Joe,
Thank you for your review comments.
I agree with you that the specification says that "The floating-point operations of the Java Virtual Machine do not throw exceptions, trap, or otherwise signal the IEEE 754 exceptional conditions of invalid operation, division by zero, overflow, underflow, or inexact." as per the JVM specification https://docs.oracle.com/javase/specs/jvms/se10/html/jvms-2.html#jvms-2.8.1.
I noticed that the SIGFPE is consumed and no exception is thrown when SIGFPE is enabled before create JVM. Hence, there is an inconsistency in the hotspot 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.Hence, the JVM behavior needs to be fixed to make the behavior consistent.
Still, I feel it makes more sense to check the sign bit to decide a number is negative or positive rather than divide-by-zro to make infinity and compare with zero. If you agree with my view, a separate bug can be opened to fix the JVM inconsistent behavior. Otherwise, we can change the component of this bug. Please comment.
Here is my rephrasing of the situation:
If someone deliberately misconfigures a CPU such that its floating-point behavior does not conform to the JVM specification, Java library code throws unexpected exceptions.
In that case, it is not a bug in the library code, it is a problem stemming from the deliberate CPU misconfiguration.
One could make a case that the new code is better in some way, perhaps faster on some platforms, but it is functionally correct as is and should not be described otherwise. The i18n team can weigh in with their assessment of the proposed patch from a maintenance perspective.
The HotSpot team could evaluate if the VM implementation should be further hardened against hostile changes to the FPU control word(s), but I would be content if this issue were closed as not a bug.
Cheers,
-Joe
Hi Joe, Naoto, Thank you for your review comments. I agree with you that as per the VM specification, divide-by-zero in DecimalFormat is allowed and hence the current fix is more of a good to have rather than a defect fix. As Joe suggested, I will see whether the new fix give better performance in any platforms. I think the current bug description may not be directly applicable to hotspot and a new bug explaining the behavior difference between before and after create JVM while handing SIGFPE may be better. Regards, Nasser From: naoto.sato@oracle.com To: joe darcy <joe.darcy@oracle.com>, Nasser Ebrahim <enasser@in.ibm.com>, core-libs-dev Libs <core-libs-dev@openjdk.java.net>, "i18n-dev@openjdk.java.net" <i18n-dev@openjdk.java.net> Date: 09/27/2018 01:55 AM Subject: Re: RFR: JDK-8211161: java.lang.ArithmeticException: divide by zero from java.text.DecimalFormat.format() Hi, Nasser, Joe, I agree with Joe as to the assessment on DecimalFormat code. The existing code looks correct. Unless there is any obvious need to replace the piece with bit operation, I'd just leave it as is. The jira issue can be transferred to HotSpot, though. Naoto On 9/26/18 11:14 AM, joe darcy wrote:
Hi Nasser,
On 9/26/2018 10:44 AM, Nasser Ebrahim wrote:
Hi Joe,
Thank you for your review comments.
I agree with you that the specification says that "The floating-point operations of the Java Virtual Machine do not throw exceptions, trap, or otherwise signal the IEEE 754 exceptional conditions of invalid operation, division by zero, overflow, underflow, or inexact." as per the JVM specification
https://docs.oracle.com/javase/specs/jvms/se10/html/jvms-2.html#jvms-2.8.1 .
I noticed that the SIGFPE is consumed and no exception is thrown when SIGFPE is enabled before create JVM. Hence, there is an inconsistency in the hotspot 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.Hence, the JVM behavior needs to be fixed to make the behavior consistent.
Still, I feel it makes more sense to check the sign bit to decide a number is negative or positive rather than divide-by-zro to make infinity and compare with zero. If you agree with my view, a separate bug can be opened to fix the JVM inconsistent behavior. Otherwise, we can change the component of this bug. Please comment.
Here is my rephrasing of the situation:
If someone deliberately misconfigures a CPU such that its floating-point
behavior does not conform to the JVM specification, Java library code throws unexpected exceptions.
In that case, it is not a bug in the library code, it is a problem stemming from the deliberate CPU misconfiguration.
One could make a case that the new code is better in some way, perhaps faster on some platforms, but it is functionally correct as is and should not be described otherwise. The i18n team can weigh in with their
assessment of the proposed patch from a maintenance perspective.
The HotSpot team could evaluate if the VM implementation should be further hardened against hostile changes to the FPU control word(s), but
I would be content if this issue were closed as not a bug.
Cheers,
-Joe
participants (3)
-
joe darcy
-
naoto.sato@oracle.com
-
Nasser Ebrahim