JDK-6989981: jstack causes "fatal error: ExceptionMark destructor expects no pending exceptions"

Staffan Larsen staffan.larsen at oracle.com
Fri Sep 20 07:34:31 PDT 2013


On 20 sep 2013, at 16:24, Yasumasa Suenaga <yasu at ysfactory.dip.jp> wrote:

> I thought your code too. However...
> 
> - These code is different from other code (rule?).

Well, you are introducing a new macro that is also different from other code, so I'm not sure how valid that argument is.

> - Similar crash cases exist. e.g. 6425580 and 7142442.
>   These crashes are different from 6989981. However, I guess that crashed
>   thread had pending exception and we need to fix with similar patch.
> 
> So I think that new macro is useful later.

Yes, similar problems may come up in other cases as well.

Generally, I don't think it's a good idea to have logging calls hidden away in general macros. What we really should do here is print some context around the stack trace as well. Something like:

    Initializing the attach listener failed with the following exception in AttachListener::init when initializing the thread_oop:

This would be possible with the code I suggested, but very hard in a general macro.

Thanks,
/Staffan


> 
> 
> Thanks,
> 
> Yasumasa
> 
> On 2013/09/20 23:05, Staffan Larsen wrote:
>> I see. CHECK_AND_CLEAR_AND_PRINT? Just kidding... :-)
>> 
>> Maybe in this case we should not have this as a macro, but actually add the code after the two calls to call_special? Something like the code below. I personally think this is more readable than obscure macros that I have to go look up to understand what they do.
>> 
>> Thanks,
>> /Staffan
>> 
>>   JavaCalls::call_special(&result, thread_oop,
>>                        klass,
>>                        vmSymbols::object_initializer_name(),
>>                        vmSymbols::threadgroup_string_void_signature(),
>>                        thread_group,
>>                        string,
>>                        THREAD);
>> 
>>   if (HAS_PENDING_EXCEPTION) {
>>     java_lang_Throwable::print(PENDING_EXCEPTION, tty);
>>     CLEAR_PENDING_EXCEPTION;
>>     return;
>>   }
>> 
>>   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
>>                         THREAD);
>> 
>>   if (HAS_PENDING_EXCEPTION) {
>>     java_lang_Throwable::print(PENDING_EXCEPTION, tty);
>>     CLEAR_PENDING_EXCEPTION;
>>     return;
>>   }
>> 
>> 
>> 
>> 
>> On 20 sep 2013, at 15:53, Yasumasa Suenaga<yasu at ysfactory.dip.jp>  wrote:
>> 
>>> Hi Staffan,
>>> 
>>> Thank you for your sponsoring!
>>> 
>>> "CHECK_AND_CLEAR" is already defined in exceptions.hpp:
>>> ******************
>>> #define CHECK_AND_CLEAR                         THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return;        } (void)(0
>>> ******************
>>> 
>>> I think that user wants why serviceability tools are failed.
>>> So I defined "CHECK_AND_CLEAR" + java_lang_Throwable::print() as "CATCH_AND_RETURN" .
>>> 
>>> 
>>> I agree rename this macro.
>>> Do you have any idea? I don't have a good name :-)
>>> 
>>> 
>>> Thanks,
>>> 
>>> Yasumasa
>>> 
>>> On 2013/09/20 20:10, Staffan Larsen wrote:
>>>> Yasuma,
>>>> 
>>>> Thanks for finding and fixing this! I have re-opened the bug. Your patch looks good to me, but perhaps CATCH_AND_RETURN should be renamed CHECK_AND_CLEAR?
>>>> 
>>>> I can sponsor the fix.
>>>> 
>>>> Thanks,
>>>> /Staffan
>>>> 
>>>> On 20 sep 2013, at 12:41, Yasumasa Suenaga<yasu at ysfactory.dip.jp>   wrote:
>>>> 
>>>>> 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
>>>>> 
>>>>> <6989981.patch><testcase.tar.gz>
>>>> 
>>> 
>> 
> 



More information about the hotspot-runtime-dev mailing list