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

missing code for an anti-dependent Phi in GCM

XMLWordPrintable

    • b03
    • b04
    • x86
    • windows_xp
    • Verified

        FULL PRODUCT VERSION :
        java version "1.6.0_12"
        Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
        Java HotSpot(TM) Server VM (build 11.2-b01, mixed mode)

        FULL OS VERSION :
        Microsoft Windows XP [Version 5.1.2600]


        A DESCRIPTION OF THE PROBLEM :
        We've found one of our programs suddenly started failing in a simple loop; depending on the exact code it would loop infinitely or cause a null pointer exception. This happened when upgrading to 1.6.0 update 10.

        We've now managed to extract the loop and trigger the bug with a simple test program, and found that:

        Java 1.6.0 update 6 and update 7 works OK.
        Java 1.6.0 update 10 to 13 fails.

        It always fails with the "-server" option, but works with "-client".
        Adding an assert for the pointer that is null, makes the program work when running with the "-ea" option.
        Using the "-Xint" option also makes the program work OK.


        THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No

        THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        run the attached reproduction program using the "-server" option.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        expected:

        C:\Documents and Settings\arnej\break>java -server -ea BreakJava
        successfully performed 1000000 cases
        successfully performed 2000000 cases
        successfully performed 3000000 cases
        successfully performed 4000000 cases
        successfully performed 5000000 cases
        successfully performed 6000000 cases
        successfully performed 7000000 cases
        [...etc...]


        actual:

        C:\Documents and Settings\arnej\break>java -server BreakJava
        ERROR: crashed during case 27456
        java.lang.NullPointerException
                at BreakJava.removeItems(BreakJava.java:53)
                at BreakJava.perform(BreakJava.java:65)
                at BreakJava.main(BreakJava.java:78)

        C:\Documents and Settings\arnej\break>java -server BreakJava
        ERROR: crashed during case 10496
        java.lang.NullPointerException
                at BreakJava.removeItems(BreakJava.java:53)
                at BreakJava.perform(BreakJava.java:65)
                at BreakJava.main(BreakJava.java:78)

        C:\Documents and Settings\arnej\break>java -server BreakJava
        ERROR: crashed during case 10816
        java.lang.NullPointerException
                at BreakJava.removeItems(BreakJava.java:53)
                at BreakJava.perform(BreakJava.java:65)
                at BreakJava.main(BreakJava.java:78)

        C:\Documents and Settings\arnej\break>java -server BreakJava
        ERROR: crashed during case 37440
        java.lang.NullPointerException
                at BreakJava.removeItems(BreakJava.java:53)
                at BreakJava.perform(BreakJava.java:65)
                at BreakJava.main(BreakJava.java:78)

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        java.lang.NullPointerException
                at BreakJava.removeItems(BreakJava.java:53)
                at BreakJava.perform(BreakJava.java:65)
                at BreakJava.main(BreakJava.java:78)


        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        public class BreakJava {

            Item list;

            static class Item {
                public Item next;
                public Item prev;
                public boolean remove;

                Item(boolean r) { remove = r; }
            }

            private void linkIn(Item item) {
                Item head = list;
                if (head == null) {
                    item.next = item;
                    item.prev = item;
                    list = item;
                } else {
                    item.next = head;
                    item.prev = head.prev;
                    head.prev.next = item;
                    head.prev = item;
                }
            }

            private void linkOut(Item item) {
                Item head = list;
                if (item.next == item) {
                    list = null;
                } else {
                    item.prev.next = item.next;
                    item.next.prev = item.prev;
                    if (head == item) {
                        list = item.next;
                    }
                }
                item.next = null;
                item.prev = null; // is this the null pointer we are seeing?
            }

            private void removeItems() {
                Item item = list;
                if (item == null) {
                    return;
                }
                Item last = item.prev;
                assert(last != null);
                boolean done = false;
                while (!done) {
                    // the original code "done = (item == last);" triggered an infinite loop
                    // and was changed slightly in order to produce an exception instead.
                    done = (item.next == last.next);
                    item = item.next;
                    if (item.prev.remove) {
                        linkOut(item.prev);
                    }
                }
            }

            public void perform(int numItems) {
                for (int i = 0; i < numItems; i++) {
                    linkIn(new Item(i == 0));
                }
                removeItems();
                list = null;
            }

            static public void main(String[] args) {
                int caseCnt = 0;
                BreakJava bj = new BreakJava();
                try {
                    for (;;) {
                        int numItems = (++caseCnt % 2);
                        if ((caseCnt % 64) == 0) {
                            numItems = 5;
                        }
                        bj.perform(numItems);
                        if ((caseCnt % 1000000) == 0) {
                            System.out.println("successfully performed " + caseCnt + " cases");
                        }
                    }
                } catch (Exception e) {
                    System.out.println("ERROR: crashed during case " + caseCnt);
                    e.printStackTrace(System.out);
                }
            }
        }

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

        CUSTOMER SUBMITTED WORKAROUND :
        using an array-based container instead of a double-linked list is a workaround in this case, but we're a bit worried about other loops using similar constructs that might trigger the same bug.

        Release Regression From : 6u7
        The above release value was the last known release where this
        bug was not reproducible. Since then there has been a regression.

              kvn Vladimir Kozlov
              ndcosta Nelson Dcosta (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: