Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
2.4.15
-
None
Description
I have been investigating a case where the IDE will not break on a line breakpoint in a test method. This method has no parameters or local variables (this affects its line number table in the bytecode) and the code is all on one line, with a chain of three method calls. When line-breaking the code or assigning to temporary, the line numbers table changes and the line breakpoints work as expected.
package a import org.junit.* final class Tests { @Test void testSomething() { // line 29 Assert.assertFalse(this.method(one(), "two", Three.class)) // line 30 } boolean method(... args) { true } def one() {} }
When compiled with Groovy 2.4 and normal/dynamic groovy, the method has line information:
Line numbers:
[pc: 4, line: 29]
[pc: 19, line: 30]
[pc: 68, line: 30]
Local variable table:
[pc: 0, pc: 109] local: this index: 0 type: a.Tests
I have not tried with the "fast path" optimization disabled. I think its prelude is what bumps the PC from 0 to 4 and results in the two PC entries for line 30 (pc 19 and pc 68).
If I assign the result of method to a new local variable, the line numbers are altered:
Line numbers: [pc: 6, line: 30] [pc: 63, line: 30] [pc: 100, line: 31] Local variable table: [pc: 0, pc: 113] local: this index: 0 type: a.Tests [pc: 6, pc: 113] local: variable index: 2 type: java.lang.Object
If I compile with invoke dynamic on, I get this for the original code:
Line numbers:
[pc: 0, line: 30]
Local variable table:
[pc: 0, pc: 30] local: this index: 0 type: a.Tests
I'm not sure the exact outcome expected here in terms of the bytecode, but I looked at similar methods from Java sources. For a Java test method, the line number table began with [pc: 0, line: whatever].
I looked at GROOVY-4505, which mentions that AsmClassGenerator.visitBlockStatement should not be writing line number information for the block statement (the source of line 29). StatementWriter.writeBlockStatement indeed retains a note about this. However, the overload in OptimizingStatementWriter still triggers `onLineNumber` from its `writeBlockStatement` -> writeGuards. Should onLineNumber check for BlockStatement and exit early? I tried this quickly and it did alter the line numbers table, but it did not help my debugger find the breakpoint on line 30.
Attachments
Issue Links
- is duplicated by
-
GROOVY-4063 Debugger Step Into doesn't work in Groovy-compiled classes when stepping filters are applied
- Closed