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.
testcase.tar.gz
Description: application/gzip-compressed