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

Yasumasa Suenaga yasu at ysfactory.dip.jp
Sat Sep 21 03:43:56 PDT 2013


Hi Staffan,

> Can you update your patch, please?

Of course!
I've attached new patch in this email.

Could you check this?


Thanks,

Yasumasa

On 2013/09/21 15:36, Staffan Larsen wrote:
>
>
>> On 20 sep 2013, at 16:49, Yasumasa Suenaga<yasu at ysfactory.dip.jp>  wrote:
>>
>>> On 2013/09/20 23:34, Staffan Larsen wrote:
>>>
>>>> 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.
>>
>> My macro is modified from "CATCH" in exceptions.hpp:
>>
>> #define CATCH                              \
>>   THREAD); if (HAS_PENDING_EXCEPTION) {    \
>>     oop ex = PENDING_EXCEPTION;            \
>>     CLEAR_PENDING_EXCEPTION;               \
>>     ex->print();                           \
>>     ShouldNotReachHere();                  \
>>   } (void)(0
>>
>> So I think that my macro is not big difference fromother code.
>>
>>
>>>> - 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.
>>
>> Agree.
>> Should we write code as following?
>>
>>    if (HAS_PENDING_EXCEPTION) {
>>      tty->print_cr("Exception in VM (AttachListener::init) : ");
>>      java_lang_Throwable::print(PENDING_EXCEPTION, tty);
>>      CLEAR_PENDING_EXCEPTION;
>>      return;
>>    }
>>
>> I like this way :-)
>
> Yes, this is what I'd like to see! Can you update your patch, please?
>
> Thanks,
> /Staffan
>
>
>>
>>
>> Thanks,
>>
>> Yasumasa
>>
>>
>>> 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>
>>
>

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: 6989981-2.patch
Url: http://mail.openjdk.java.net/pipermail/serviceability-dev/attachments/20130921/c1527604/6989981-2.patch 


More information about the serviceability-dev mailing list