Subject: suprious SIGFPE on i386?
To: None <tech-kern@netbsd.org>
From: Simon Gerraty <sjg@juniper.net>
List: tech-kern
Date: 06/25/2002 12:41:07
Is anyone seeing spurious SIGFPE's on i386?

This is may be a bug in JDK, but I haven't built it in a long time and
I'm getting the same behaviour on two separate P3's one running 1.5ZC
and the other running 1.6_BETA1.

The JDK is attempting to initialize a SecureRandom.  During this
process it spawns a bunch of threads and spins calling gettimeofday().
Running under gdb I typically see:

Continuing.

Program received signal SIGFPE, Arithmetic exception.
0x480e019b in gettimeofday () from /usr/lib/libc.so.12

but I think this is only because gettimeofday is being called a lot.

If I continue I may get an exception thrown:

Exception in thread "main" java.lang.ExceptionInInitializerError: java.lang.IllegalArgumentException: Illegal Load: 0.75
        at java.util.Hashtable.<init>(Hashtable.java:148)
        at java.util.Hashtable.<init>(Hashtable.java:174)

This is thrown because the float value 0.75 is either <= 0 or NaN -
neither of which is true but I imagine a spurious SIGFPE would make it
think NaN.  Of course as soon as I split that into two separate
exceptions I can't repeat it :-)

If I set gdb to not stop and not pass SIGFPE, the program runs to
completion - with 100's of:

Program received signal SIGFPE, Arithmetic exception.

being output.

The same JDK compiled on freebsd works fine, and the linux JDK
(/usr/pkg/java) runs the test prog fine on both machines so I doubt it
is hardware.  Using classic VM with green_threads in each case.

Any clues as to how to pursue this?  Has anything FP related changed
on i386 since say 1.5 - perhaps the JDK needs to initialize something
differently?   This same SIGFPE thing happens with AWT apps too.
Apps like javac work fine.

The test case fwiw is:

import java.security.*;

public class prng {
  public static void main (String args[]) {
    try {
      SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");

      byte bytes[] = new byte[16];
      sr.nextBytes(bytes);
      System.out.println("got: " + bytes);
      byte seed[] = sr.generateSeed(16);
      System.out.println("got: " + seed);
      System.exit(0);
    } catch (Exception e) {
      System.exit(1);
    }
  }
}

Thanks
--sjg