Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-8742

Line number information for method is confusing debugger




      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 {
        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.


          Issue Links



              • Assignee:
                paulk Paul King
                emilles Eric Milles
              • Votes:
                1 Vote for this issue
                3 Start watching this issue


                • Created: