Apparant bug in the JVM
Rickard Bäckman
rickard.backman at oracle.com
Mon Nov 11 05:32:14 PST 2013
Stephen,
it's been fixed in b115.
Bug: JDK-8027622
Thanks
/R
On 11/11, Stephen Colebourne wrote:
> I was sent this piece of test code by Dirk Lemmermann. It fails
> randomly on JDK8 b114
>
> import static java.time.temporal.ChronoUnit.DAYS;
> import java.time.Instant;
>
> public class TestInstantBug {
> public static void main(String[] args) {
> Instant now = Instant.now();
> System.out.println("now = " + now);
> for (int i = 0; i < 100000; i++) {
> System.out.println(i);
> Instant truncated = now.truncatedTo(DAYS);
> System.out.println(truncated);
> }
> }
> }
>
> The code does not change any variables during the loop. Instant is
> immutable and well written to my knowledge.
>
> My debugging shows some horrible behaviour.
>
> I copied Instant.java and edited it, adding it to the bootclasspath.
> This is the original code in Instant.java:
> private static Instant create(long seconds, int nanoOfSecond) {
> if ((seconds | nanoOfSecond) == 0) {
> return EPOCH;
> }
> if (seconds < MIN_SECOND || seconds > MAX_SECOND) {
> throw new DateTimeException("Instant exceeds minimum or
> maximum instant");
> }
> return new Instant(seconds, nanoOfSecond);
> }
>
> The second if statement randomly fails.
> Worse, the use of a System.out.println() on the "seconds" variable
> causes the if statement to reset.
>
> Given this test code:
>
> private static Instant create(long seconds, int nanoOfSecond) {
> if ((seconds | nanoOfSecond) == 0) {
> return EPOCH;
> }
> System.out.println(seconds < MIN_SECOND || seconds > MAX_SECOND);
> if (seconds < MIN_SECOND || seconds > MAX_SECOND) {
> System.out.println(MIN_SECOND);
> System.out.println(MAX_SECOND);
> System.out.println(seconds);
> System.out.println(seconds < MIN_SECOND);
> System.out.println(seconds > MAX_SECOND);
> System.out.println(seconds < MIN_SECOND || seconds > MAX_SECOND);
> System.out.println("Create " + seconds);
> System.out.println(MIN_SECOND);
> System.out.println(MAX_SECOND);
> System.out.println(seconds);
> System.out.println(seconds < MIN_SECOND);
> System.out.println(seconds > MAX_SECOND);
> System.out.println(seconds < MIN_SECOND || seconds > MAX_SECOND);
> throw new DateTimeException("Instant exceeds minimum or
> maximum instant");
> }
> return new Instant(seconds, nanoOfSecond);
> }
>
> the output is (when it actually fails):
> true // the if statement randomly returned true
> -31557014167219200
> 31556889864403199
> 1384128000
> false // the two parts of the if statement return false
> false // the two parts of the if statement return false
> true // the if statement still returns true
> Create 1384128000 // system out resets it
> -31557014167219200
> 31556889864403199
> 1384128000
> false
> false
> false // the if statement returns false
> Exception in thread "main" java.time.DateTimeException: Instant
> exceeds minimum or maximum instant
> at java.time.Instant.create(Instant.java:422)
> at java.time.Instant.ofEpochSecond(Instant.java:327)
> at java.time.Instant.plus(Instant.java:940)
> at java.time.Instant.plusNanos(Instant.java:918)
> at java.time.Instant.truncatedTo(Instant.java:773)
> at TestInstantBug.main(TestInstantBug.java:13)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:483)
> at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
>
> Hope you can squash this bug. b114 needs a big warning sign on it.
>
> Stephen
More information about the hotspot-dev
mailing list