Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4644270

EXCEPTION_FLT_DIVIDE_BY_ZERO with Floating Point Arithmetic using external dll

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 1.4.0
    • core-libs
    • x86
    • windows_nt



      Name: jl125535 Date: 02/27/2002


      FULL PRODUCT VERSION :
      java version "1.4.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
      Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)


      FULL OPERATING SYSTEM VERSION : Windows NT Version 4.0
      (Build 1381, Service Pack 5)


      A DESCRIPTION OF THE PROBLEM :
      We use a dll to do some calculations. It is a C-dll calling
      a Delphi-dll (pascal).
      With one call to an standard arithmetic function in the
      Delphi-dll (int(..)), returning to the Java VM and calling
      an DecimalFormat.format, the Java VM will crash with
      an "EXCEPTION_FLT_DIVIDE_BY_ZERO occurred at PC=0xADBD38".

      The crash occures in DecimalFormat.format()
      ...
      boolean isNegative = (number < 0.0) || (number == 0.0 &&
      1/number < 0.0);
      ...
      while dividing "1/number", if number is 0.0 (which is
      normally allowed in Java -> Infinity).

      The arithmetic function "int()" in the dll cuts the
      fractional part of the number, so we assume a problem with
      the floating point unit, but without any help we can't
      verify that.
      The "frac()"-function causes the same problem.
      Without calling that functions, all works fine.

      There is one other testcase, where we had a crash in the
      awt.dll in older JDK-Versions, but this does not happen
      with the actual version (1.4).
      I think, that there is a relation between these crashes.
      We have a complete small testcase for both problems.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Load external C-/Delphi-dll
      2. Call external method, which uses described arithmetic
      function ("int()" or "frac()")
      3. Create an DecimalFormatter
      4. Use DecimalFormat.format with an value of 0.0

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      C:\testdelphi>java test.TestDelphiDll
      TestDelphiDll: TSTDELPH.DLL geladen
      calling test_DelphiCall() ...
      Java_test_TestDelphiDll_JniTestDelphi() calling ...
      Laden der Bibliothek lva32.dll!
      Calling function entry() ...
      entryRet = 456832
      Java_test_TestDelphiDll_JniTestDelphi() finishing ...
      test_DelphiCall() called ...
      Now DecimalFormat.format ...

      Unexpected Signal : EXCEPTION_FLT_DIVIDE_BY_ZERO occurred at PC=0xADBD38
      Function=[Unknown.]
      Library=(N/A)

      NOTE: We are unable to locate the function name symbol for the error
            just occurred. Please refer to release documentation for possible
            reason and solutions.


      Current Java thread:

      Dynamic libraries:
      0x00400000 - 0x00406000 c:\java\j2sdk1.4.0\bin\java.exe
      0x77F70000 - 0x77FD0000 C:\WINNT\System32\ntdll.dll
      0x77DC0000 - 0x77DFF000 C:\WINNT\system32\ADVAPI32.dll
      0x77F00000 - 0x77F62000 C:\WINNT\system32\KERNEL32.dll
      0x77E70000 - 0x77EC4000 C:\WINNT\system32\USER32.dll
      0x77ED0000 - 0x77EFC000 C:\WINNT\system32\GDI32.dll
      0x77E10000 - 0x77E67000 C:\WINNT\system32\RPCRT4.dll
      0x78000000 - 0x78046000 C:\WINNT\system32\MSVCRT.dll
      0x6D330000 - 0x6D442000 c:\java\j2sdk1.4.0\jre\bin\client\jvm.dll
      0x77FD0000 - 0x77FFB000 C:\WINNT\System32\WINMM.dll
      0x72FE0000 - 0x72FE8000 C:\WINNT\System32\mmdrv.dll
      0x6BC00000 - 0x6BC17000 C:\WINNT\System32\sb16snd.dll
      0x71700000 - 0x7178A000 C:\WINNT\system32\COMCTL32.dll
      0x6D1D0000 - 0x6D1D7000 c:\java\j2sdk1.4.0\jre\bin\hpi.dll
      0x6D300000 - 0x6D30D000 c:\java\j2sdk1.4.0\jre\bin\verify.dll
      0x6D210000 - 0x6D228000 c:\java\j2sdk1.4.0\jre\bin\java.dll
      0x6D320000 - 0x6D32D000 c:\java\j2sdk1.4.0\jre\bin\zip.dll
      0x10000000 - 0x10033000 C:\testdelphi\tstdelph.dll
      0x0AEC0000 - 0x0AED3000 C:\testdelphi\lva32.dll
      0x65340000 - 0x653D2000 C:\WINNT\system32\oleaut32.dll
      0x77B80000 - 0x77C36000 C:\WINNT\system32\ole32.dll
      0x41000000 - 0x4100B000 C:\testdelphi\borlndmm.dll
      0x76AE0000 - 0x76AFD000 C:\WINNT\System32\imagehlp.dll
      0x731B0000 - 0x731BA000 C:\WINNT\System32\PSAPI.DLL

      Local Time = Tue Feb 26 16:15:45 2002


      ****************
      Another exception has been detected while we were handling last error.
      Dumping information about last error:
      ERROR REPORT FILE = (N/A)
      PC = 0x00ADBD38
      SIGNAL = -1073741682
      FUNCTION NAME = (N/A)
      OFFSET = 0xFFFFFFFF
      LIBRARY NAME = (N/A)
      Please check ERROR REPORT FILE for further information, if there is any.
      Good bye.


      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      We have a complete little testcase to reproduce the bug. Please ask for it.

      The Java-Programm looks like:
      import java.text.*;
      import java.util.*;

      public class TestDelphiDll
      {
        private native int JniTestDelphi();

        public TestDelphiDll()
        {
          test_DelphiCall();
        }

        public static void main(String args[])
        {
          TestDelphiDll testDelphiDll1 = new TestDelphiDll();
          System.exit(0);
        }

        private void test_DelphiCall()
        {
          System.out.println("calling test_DelphiCall() ...");

          JniTestDelphi();

          System.out.println("test_DelphiCall() called ...");

          Double wertObject = new Double("0");
          double wertPre = wertObject.doubleValue();
          double wert = Math.abs(wertPre);

          DecimalFormat formatter;
          NumberFormat numberformat = NumberFormat.getInstance();
          if(numberformat instanceof DecimalFormat)
          {
            formatter = (DecimalFormat)numberformat;
          }
          else
          {
            NumberFormat numberformat1 = NumberFormat.getInstance(Locale.US);
            if(numberformat1 instanceof DecimalFormat)
              formatter = (DecimalFormat)numberformat1;
            else
              throw new Error("Could not get a DecimalFormat for the current
      locale!!");
          }

          DecimalFormat decimalformat = (DecimalFormat)formatter.clone();
          StringBuffer stringbuffer = new StringBuffer();
          FieldPosition fieldposition = new FieldPosition(1);
          decimalformat.setMaximumFractionDigits(1000);
          decimalformat.setMinimumFractionDigits(0);

          // Now Division by zero
          System.out.println("Now DecimalFormat.format ...");
          decimalformat.format(wert, stringbuffer, fieldposition);
        }

        static
        {
            try
            {
                System.loadLibrary("TSTDELPH");
                System.out.println("TestDelphiDll: TSTDELPH.DLL geladen");
            }
            catch(UnsatisfiedLinkError e)
            {
                e.printStackTrace();
            }
        }
      }

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

      CUSTOMER WORKAROUND :

      ======================================================================

      You can patch the DecimalFormat-Class by detecting the sign
      bit without Division by zero.

      boolean isNegative = (number < 0.0) ||
              (number == 0.0 && (Double.doubleToLongBits(number)
      & 0x8000000000000000L) != 0L);
              if (isNegative) number = -number;

      Btw: Isn't this version not better for detecting the sign-
      bit ?
      (Review ID: 143369)

            darcy Joe Darcy
            jleesunw Jon Lee (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: