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

jdb: Incorrect stepping inside finally block

    Details

    • Subcomponent:
    • Resolved In Build:
      b89
    • Verification:
      Verified

      Backports

        Description

        $ jdb Main
        Initializing jdb ...
        > stop at Main:9
        Deferring breakpoint Main:9.
        It will be set after the class is loaded.
        > run
        run Main
        Set uncaught java.lang.Throwable
        Set deferred uncaught java.lang.Throwable
        >
        VM Started: Set deferred breakpoint Main:9

        Breakpoint hit: "thread=main", Main.test(), line=9 bci=2
        9 if (args.length < - 1) { // Any non-trivial condition evaluating to `false` would do

        main[1] step
        >
        Step completed: "thread=main", Main.test(), line=10 bci=16
        10 System.out.println("not null");

        Source:
        public class Main {
          public static void main(String[] args) {
            test(args);
          }
          public static Void test(String[] args) {
            try {
              return null;
            } finally {
              if (args.length < - 1) { // Any non-trivial condition evaluating to `false` would do
                System.out.println("not null");
              }
            }
          }
        }

          Activity

          Hide
          aeriksso Andreas Eriksson (Inactive) added a comment -
          Problem is that linenumbers are not generated correctly by javac.

          Suggested fix:

          diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
          --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
          +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
          @@ -1697,6 +1697,11 @@
               public void visitReturn(JCReturn tree) {
                   int limit = code.nextreg;
                   final Env<GenContext> targetEnv;
          +
          + /* Save and then restore the location of the return in case a finally
          + * is expanded (with unwind()) in the middle of our bytecodes.
          + */
          + int tmpPos = code.pendingStatPos;
                   if (tree.expr != null) {
                       Item r = genExpr(tree.expr, pt).load();
                       if (hasFinally(env.enclMethod, env)) {
          @@ -1704,17 +1709,10 @@
                           r.store();
                       }
                       targetEnv = unwind(env.enclMethod, env);
          + code.pendingStatPos = tmpPos;
                       r.load();
                       code.emitop0(ireturn + Code.truncate(Code.typecode(pt)));
                   } else {
          - /* If we have a statement like:
          - *
          - * return;
          - *
          - * we need to store the code.pendingStatPos value before generating
          - * the finalizer.
          - */
          - int tmpPos = code.pendingStatPos;
                       targetEnv = unwind(env.enclMethod, env);
                       code.pendingStatPos = tmpPos;
                       code.emitop0(return_);
          Show
          aeriksso Andreas Eriksson (Inactive) added a comment - Problem is that linenumbers are not generated correctly by javac. Suggested fix: diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -1697,6 +1697,11 @@      public void visitReturn(JCReturn tree) {          int limit = code.nextreg;          final Env<GenContext> targetEnv; + + /* Save and then restore the location of the return in case a finally + * is expanded (with unwind()) in the middle of our bytecodes. + */ + int tmpPos = code.pendingStatPos;          if (tree.expr != null) {              Item r = genExpr(tree.expr, pt).load();              if (hasFinally(env.enclMethod, env)) { @@ -1704,17 +1709,10 @@                  r.store();              }              targetEnv = unwind(env.enclMethod, env); + code.pendingStatPos = tmpPos;              r.load();              code.emitop0(ireturn + Code.truncate(Code.typecode(pt)));          } else { - /* If we have a statement like: - * - * return; - * - * we need to store the code.pendingStatPos value before generating - * the finalizer. - */ - int tmpPos = code.pendingStatPos;              targetEnv = unwind(env.enclMethod, env);              code.pendingStatPos = tmpPos;              code.emitop0(return_);
          Hide
          aeriksso Andreas Eriksson (Inactive) added a comment -
          After re-compiling the java class file with the above change the stepping displays the expected output:

          > stop at Main:9
          Deferring breakpoint Main:9.
          It will be set after the class is loaded.
          > run
          run Main
          [...]
          Breakpoint hit: "thread=main", Main.test(), line=9 bci=2
          9 if (args.length < - 1) { // Any non-trivial condition evaluating to 'false' would do

          main[1] step
          >
          Step completed: "thread=main", Main.test(), line=7 bci=16
          7 return null;
          Show
          aeriksso Andreas Eriksson (Inactive) added a comment - After re-compiling the java class file with the above change the stepping displays the expected output: > stop at Main:9 Deferring breakpoint Main:9. It will be set after the class is loaded. > run run Main [...] Breakpoint hit: "thread=main", Main.test(), line=9 bci=2 9 if (args.length < - 1) { // Any non-trivial condition evaluating to 'false' would do main[1] step > Step completed: "thread=main", Main.test(), line=7 bci=16 7 return null;
          Hide
          hgupdate HG Updates added a comment -
          URL: http://hg.openjdk.java.net/jdk9/dev/langtools/rev/16873e56156e
          User: aeriksso
          Date: 2015-10-27 09:39:03 +0000
          Show
          hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/dev/langtools/rev/16873e56156e User: aeriksso Date: 2015-10-27 09:39:03 +0000
          Hide
          hgupdate HG Updates added a comment -
          URL: http://hg.openjdk.java.net/jdk9/jdk9/langtools/rev/16873e56156e
          User: lana
          Date: 2015-10-28 19:24:29 +0000
          Show
          hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/jdk9/langtools/rev/16873e56156e User: lana Date: 2015-10-28 19:24:29 +0000

            People

            • Assignee:
              aeriksso Andreas Eriksson (Inactive)
              Reporter:
              shadowbug Shadow Bug
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: