changeset 2759:ec5ce9326985

6865265: JVM crashes with "missing exception handler" error Summary: Retry the call to fast_exception_handler_bci_for() after it returned with a pending exception. Don't cache the exception handler pc computed by compute_compiled_exc_handler() if the handler is for another (nested) exception. Reviewed-by: kamg, kvn Contributed-by: volker.simonis@gmail.com
author kvn
date Tue, 04 Oct 2011 14:30:04 -0700
parents 940513efe83a
children eba73e0c7780
files src/share/vm/opto/runtime.cpp src/share/vm/runtime/sharedRuntime.cpp test/compiler/6865265/StackOverflowBug.java
diffstat 3 files changed, 100 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/runtime.cpp	Tue Oct 04 10:07:07 2011 -0700
+++ b/src/share/vm/opto/runtime.cpp	Tue Oct 04 14:30:04 2011 -0700
@@ -997,10 +997,13 @@
         force_unwind ? NULL : nm->handler_for_exception_and_pc(exception, pc);
 
       if (handler_address == NULL) {
+        Handle original_exception(thread, exception());
         handler_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true);
         assert (handler_address != NULL, "must have compiled handler");
-        // Update the exception cache only when the unwind was not forced.
-        if (!force_unwind) {
+        // Update the exception cache only when the unwind was not forced
+        // and there didn't happen another exception during the computation of the
+        // compiled exception handler.
+        if (!force_unwind && original_exception() == exception()) {
           nm->add_handler_for_exception_and_pc(exception,pc,handler_address);
         }
       } else {
--- a/src/share/vm/runtime/sharedRuntime.cpp	Tue Oct 04 10:07:07 2011 -0700
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Tue Oct 04 14:30:04 2011 -0700
@@ -659,12 +659,14 @@
   int scope_depth = 0;
   if (!force_unwind) {
     int bci = sd->bci();
+    bool recursive_exception = false;
     do {
       bool skip_scope_increment = false;
       // exception handler lookup
       KlassHandle ek (THREAD, exception->klass());
       handler_bci = sd->method()->fast_exception_handler_bci_for(ek, bci, THREAD);
       if (HAS_PENDING_EXCEPTION) {
+        recursive_exception = true;
         // We threw an exception while trying to find the exception handler.
         // Transfer the new exception to the exception handle which will
         // be set into thread local storage, and do another lookup for an
@@ -680,6 +682,9 @@
           skip_scope_increment = true;
         }
       }
+      else {
+        recursive_exception = false;
+      }
       if (!top_frame_only && handler_bci < 0 && !skip_scope_increment) {
         sd = sd->sender();
         if (sd != NULL) {
@@ -687,7 +692,7 @@
         }
         ++scope_depth;
       }
-    } while (!top_frame_only && handler_bci < 0 && sd != NULL);
+    } while (recursive_exception || (!top_frame_only && handler_bci < 0 && sd != NULL));
   }
 
   // found handling method => lookup exception handler
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/6865265/StackOverflowBug.java	Tue Oct 04 14:30:04 2011 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6865265
+ * @summary JVM crashes with "missing exception handler" error
+ * @author volker.simonis@sap.com
+ *
+ * @run main/othervm -XX:CompileThreshold=100 -Xbatch -Xss128k StackOverflowBug
+ */
+
+
+public class StackOverflowBug {
+
+  public static int run() {
+    try {
+      try {
+        return run();
+      } catch (Throwable e) {
+        // Notice that the class 'Throwable' is NOT resolved by the verifier,
+        // because the verifier only checks if 'Throwable' is assignable to
+        // 'java.lang.Throwable' and this check succeeds immediately if the two
+        // types have equal names (see 'VerificationType::is_assignable_from' which
+        // is called from 'ClassVerifier::verify_exception_handler_table').
+        // This is strange, because if the two classes have different names,
+        // 'is_assignable_from()' calls 'is_reference_assignable_from()' which resolves
+        // both classes by calling 'SystemDictionary::resolve_or_fail()'. This call
+        // also takes into account the current class loader (i.e. the one which was used
+        // to load this class) and would place a corresponding
+        // "java.lang.Throwable / current-Classloader" entry into the system dictionary.
+        // This would in turn allow C2 to see 'java.lang.Throwable' as "loaded"
+        // (see 'Parse::catch_inline_exceptions()') when this method is compiled.
+        return 42;
+      }
+    }
+    finally {
+    }
+  }
+
+  public static void main(String argv[]) {
+    run();
+  }
+}
+
+/*
+  public static int run();
+    Code:
+       0: invokestatic  #2                  // Method run:()I
+       3: istore_0
+       4: iload_0
+       5: ireturn
+       6: astore_0
+       7: bipush        42
+       9: istore_1
+      10: iload_1
+      11: ireturn
+      12: astore_2
+      13: aload_2
+      14: athrow
+    Exception table:
+       from    to  target type
+           0     4     6   Class java/lang/Throwable
+           0     4    12   any
+           6    10    12   any
+          12    13    12   any
+
+ */