Apparant bug in the JVM
Stephen Colebourne
scolebourne at joda.org
Mon Nov 11 05:42:48 PST 2013
Cool, must have missed the linked threads.
Stephen
On 11 November 2013 13:32, Rickard Bäckman <rickard.backman at oracle.com> wrote:
> 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