Hi,

I encountered this bug:
  JDK-6989981: jstack causes "fatal error: ExceptionMark destructor expects no 
pending exceptions"

I read hs_err and attachListener.cpp, Java heap usage is very high and
it could be OutOfMemoryError in AttachListener::init() .

If JavaCalls::call_special() in AttachListener::init() fail which is
caused by OOME, d'tor of EXCEPTION_MARK (~ExceptionMark) will generate
internal error.

So I make a patch for avoiding crash and attached in this email (6989981.patch) 
.
I'd like to re-open this bug and contribute my patch.
Could you help me?


--- DETAILS ---
CHECK macro is used in JavaCalls::call_special() .

******************
void AttachListener::init() {
  EXCEPTION_MARK;

       :

  // Initialize thread_oop to put it into the system threadGroup
  Handle thread_group (THREAD, Universe::system_thread_group());
  JavaValue result(T_VOID);
  JavaCalls::call_special(&result, thread_oop,
                       klass,
                       vmSymbols::object_initializer_name(),
                       vmSymbols::threadgroup_string_void_signature(),
                       thread_group,
                       string,
                       CHECK);

  KlassHandle group(THREAD, SystemDictionary::ThreadGroup_klass());
  JavaCalls::call_special(&result,
                        thread_group,
                        group,
                        vmSymbols::add_method_name(),
                        vmSymbols::thread_void_signature(),
                        thread_oop,             // ARG 1
                        CHECK);
******************

CHECK macro does not clear pending exception of current thread.
So call_special() fails with runtime exception, d'tor of ExceptionMark
generates fatal error.

******************
ExceptionMark::~ExceptionMark() {
  if (_thread->has_pending_exception()) {
    Handle exception(_thread, _thread->pending_exception());
    _thread->clear_pending_exception(); // Needed to avoid infinite recursion
    if (is_init_completed()) {
      exception->print();
      fatal("ExceptionMark destructor expects no pending exceptions");
    } else {
      vm_exit_during_initialization(exception);
    }
  }
}
******************


--- HOW TO REPRODUCE ---
I also crate testcase of this issue (testcase.tar.gz) . This testcase contains
two modules.

 - jvmti: JVMTI agent for this issue. This agent traps SIGQUIT and
          calls original (in HotSpot) SIGQUIT handler.
          This signal handler is invoked, MethodEntry event callback is
          enabled. MethodEntry generates OutOfMemoryError.

 - java : Simple long sleep program.

I can run this testcase in Fedora18 x86_64. See below.

-------
$ javac java/LongSleep.java
$ make -C jvmti
make: Entering directory `/data/share/patch/ExceptionMark/testcase/jvmti'
gcc -I/usr/lib/jvm/java-openjdk/include 
-I/usr/lib/jvm/java-openjdk/include/linux -fPIC -c oome.c
gcc -shared -o liboome.so oome.o
make: Leaving directory `/data/share/patch/ExceptionMark/testcase/jvmti'
$ export JAVA_HOME=</path/to/jre>
$ ./test.sh
-------



Best regards,

Yasumasa

diff -r 9ed97b511b26 src/share/vm/services/attachListener.cpp
--- a/src/share/vm/services/attachListener.cpp  Thu Sep 19 11:04:23 2013 -0400
+++ b/src/share/vm/services/attachListener.cpp  Fri Sep 20 15:47:51 2013 +0900
@@ -470,7 +470,7 @@
                        vmSymbols::threadgroup_string_void_signature(),
                        thread_group,
                        string,
-                       CHECK);
+                       CATCH_AND_RETURN);
 
   KlassHandle group(THREAD, SystemDictionary::ThreadGroup_klass());
   JavaCalls::call_special(&result,
@@ -479,7 +479,7 @@
                         vmSymbols::add_method_name(),
                         vmSymbols::thread_void_signature(),
                         thread_oop,             // ARG 1
-                        CHECK);
+                        CATCH_AND_RETURN);
 
   { MutexLocker mu(Threads_lock);
     JavaThread* listener_thread = new 
JavaThread(&attach_listener_thread_entry);
diff -r 9ed97b511b26 src/share/vm/utilities/exceptions.hpp
--- a/src/share/vm/utilities/exceptions.hpp     Thu Sep 19 11:04:23 2013 -0400
+++ b/src/share/vm/utilities/exceptions.hpp     Fri Sep 20 15:47:51 2013 +0900
@@ -284,6 +284,13 @@
     ShouldNotReachHere();                  \
   } (void)(0
 
+#define CATCH_AND_RETURN                                \
+  THREAD); if (HAS_PENDING_EXCEPTION) {                 \
+    java_lang_Throwable::print(PENDING_EXCEPTION, tty); \
+    CLEAR_PENDING_EXCEPTION;                            \
+    return;                                             \
+  } (void)(0
+
 // ExceptionMark is a stack-allocated helper class for local exception 
handling.
 // It is used with the EXCEPTION_MARK macro.
 

Attachment: testcase.tar.gz
Description: application/gzip-compressed

Reply via email to