Closed stephan-herrmann closed 3 days ago
Those are Heisenbugs: they reliably fail except when run in debug mode :(
Those are Heisenbugs: they reliably fail except when run in debug mode :(
Wow, hard-core Heisenbug, no debugger needed to send the bug into hiding:
final int getExtendedEnd(ASTNode node) {
TargetSourceRangeComputer.SourceRange range= getExtendedRange(node);
return range.getStartPosition() + range.getLength();
}
final int getExtendedEnd(ASTNode node) {
TargetSourceRangeComputer.SourceRange range= getExtendedRange(node);
if (range == null) {
System.out.println();
}
return range.getStartPosition() + range.getLength();
}
The null
in question is produced by this method in NoCommentSourceRangeComputer:
public SourceRange computeSourceRange(ASTNode node) {
return new SourceRange(node.getStartPosition(), node.getLength());
}
For lack of debugability I reduced the test suite to
At that point I could disable GC to reduce non-determinism:
-Xmx4G
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
With this setup, the error was fairly stable, but the boarder of what tests could be removed without "breaking" the bug was not 100% deterministic.
Finally I added the following harness in ASTRewriteAnalyzer:
final int getExtendedEnd(ASTNode node) {
try {
TargetSourceRangeComputer.SourceRange range= getExtendedRange(node);
return range.getStartPosition() + range.getLength();
} catch (NullPointerException npe) {
System.err.println(extendedSourceRangeComputer);
npe.printStackTrace();
System.err.println(extendedSourceRangeComputer.computeSourceRange(node));
System.err.flush();
System.exit(-13);
}
}
See the implementation of getExtendedRange()
:
final SourceRange getExtendedRange(ASTNode node) {
if (this.eventStore.isRangeCopyPlaceholder(node)) {
return new SourceRange(node.getStartPosition(), node.getLength());
}
return this.extendedSourceRangeComputer.computeSourceRange(node);
}
and be told that the field extendedSourceRangeComputer
is final.
Output is:
org.eclipse.jdt.internal.corext.refactoring.util.NoCommentSourceRangeComputer@5be09f8
java.lang.NullPointerException: Cannot invoke "org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer$SourceRange.getStartPosition()" because "range" is null
at org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.getExtendedEnd(ASTRewriteAnalyzer.java:275)
at org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.doVisit(ASTRewriteAnalyzer.java:439)
at org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.voidVisitList(ASTRewriteAnalyzer.java:476)
at org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.voidVisit(ASTRewriteAnalyzer.java:470)
at org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.doVisitUnchangedChildren(ASTRewriteAnalyzer.java:483)
at org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.visit(ASTRewriteAnalyzer.java:4150)
at org.eclipse.jdt.core.dom.VariableDeclarationStatement.accept0(VariableDeclarationStatement.java:246)
[...]
org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer$SourceRange@4348b168
This reports the following sequence of events:
getExtendedRange(node)
returns null
which comes from one of
new SourceRange(node.getStartPosition(), node.getLength())
-- funny, huh?this.extendedSourceRangeComputer.computeSourceRange(node);
extendedSourceRangeComputer
holds an instance of NoCommentSourceRangeComputer
(see implementation at the top of this comment)extendedSourceRangeComputer.computeSourceRange(node)
returns an instance of TargetSourceRangeComputer$SourceRange
Ergo: the null
cannot possibly have happened. Yet NPE was thrown.
Noting furthermore that the errors occur only when running on JDK 23. Noting furthermore that we don't have a lot of alternatives of JDK 23 (only openjdk EA available at this point).
I'll be researching options to disable JIT for some code parts...
I'll be researching options to disable JIT for some code parts...
This helps:
-XX:CompileCommand=exclude,org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer::getExtendedRange
Ergo: JIT bug :eyes:
If others can verify, then we will have to add a BIG ALERT in some top-level documentation (once Java 23 is GA).
I'll play with p2.inf
for adding these options when installing the java23 patch...
Let's wait for next test results from https://ci.eclipse.org/releng/job/YPBuilds/job/ep433Y-unit-cen64-gtk3-java23/lastCompletedBuild/testReport/ (which seems to be the only job that runs tests on Java 23).
Let's wait for next test results from https://ci.eclipse.org/releng/job/YPBuilds/job/ep433Y-unit-cen64-gtk3-java23/lastCompletedBuild/testReport/ (which seems to be the only job that runs tests on Java 23).
https://ci.eclipse.org/releng/job/YPBuilds/job/ep433Y-unit-cen64-gtk3-java23/23/ still shows 458 failures / errors. It seems pom.xml isn't used during that build but test.xml. Trying to cover that path, too, via https://github.com/eclipse-jdt/eclipse.jdt.ui/pull/1642
YES, finally the JIT-bug workaround worked, latest test run https://ci.eclipse.org/releng/job/YPBuilds/job/ep433Y-unit-cen64-gtk3-java23/25/testReport/ is down to 6 failures total, of which only 6 are in JDT (Core).
After seeing 478 failures in https://ci.eclipse.org/releng/job/YPBuilds/job/ep433Y-unit-cen64-gtk3-java23/lastCompletedBuild/testReport/ I succeeded to reproduce 415 such locally with latest from BETA_JAVA23 of relevant JDT projects.