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

JDK8,JDK9-breakpoint on a continue doesnt work on jdb and intellij

XMLWordPrintable

      From a comment below:
      https://bugs.openjdk.java.net/browse/JDK-8208664?focusedCommentId=14202472&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14202472

      public class Cont {
         public static void main(String[] args) {
             foo(true, false);
         }

         static void foo(boolean a, boolean b) {
             int i;
             for (i = 0; i < 10; i++) {
                 if (a || b) {
                     continue; // breakpoint here does not work
                 }
                 System.out.println(i);
             }
             System.out.println(i);
         }
      }

      Breakpoint at "continue" statement (line 10) does not trigger. javap shows the following bytecodes.

               0: iconst_0
               1: istore_2
               2: iload_2
               3: bipush 10
               5: if_icmpge 32
               8: iload_0
               9: ifne 26
              12: iload_1
              13: ifeq 19
              16: goto 26
              19: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
              22: iload_2
              23: invokevirtual #4 // Method java/io/PrintStream.println:(I)V
              26: iinc 2, 1
              29: goto 2
              32: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
              35: iload_2
              36: invokevirtual #4 // Method java/io/PrintStream.println:(I)V
              39: return
            LineNumberTable:
              line 8: 0
              line 9: 8
              line 10: 16
              line 12: 19
              line 8: 26
              line 14: 32
              line 15: 39

      The LineNumberTable says the "continue" at line 10 maps to the goto bytecode at line 16. However, the bytecodes at lines 8-9 are loading and checking 'a', and doing the goto (ifeq) for the continue at bytecode 9. So essentially the continue at line 10 logically maps to two separate goto's, one at bytecode offset 9 (ifeq) and one at bytecode offset 16, and the LineNumberTable only has the one at bytecode offset 16.

      Adding a println before the continue causes different bytecode logic to be generated that doesn't have this problem:

               5: if_icmpge 40
               8: iload_0
               9: ifne 16
              12: iload_1
              13: ifeq 27
              16: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
              19: ldc #4 // String about to continue...
              21: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
              24: goto 34

              line 11: 24

      I don't think this should be considered a jvmti or debugger bug. The issue lies in how javac is generating bytecodes, including the LineNumberTable. In order for this to work with the bytecode as generated, the LineNumberTable would need two entries for line #10, one at bytecode 9 and one at 16.

            jlahoda Jan Lahoda
            shadowbug Shadow Bug
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: