Duplicate :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
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.
|