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

Dmitry Samersoff dmitry.samersoff at oracle.com
Sun Sep 22 01:51:08 PDT 2013


Yasumasa,

Looks good for me.

-Dmitry

On 2013-09-21 14:43, Yasumasa Suenaga wrote:
> 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>
>>>
>>
> 


-- 
Dmitry Samersoff
Oracle Java development team, Saint Petersburg, Russia
* I would love to change the world, but they won't give me the source code.


More information about the serviceability-dev mailing list