RFR JDK-8021954 VM SIGSEGV during classloading on MacOS; hs_err_pid file produced

Coleen Phillimore coleen.phillimore at oracle.com
Tue Aug 27 13:08:57 PDT 2013


On 08/27/2013 03:42 PM, Lois Foltan wrote:
>
> On 8/27/2013 1:49 PM, Christian Thalinger wrote:
>>
>> On Aug 27, 2013, at 5:44 AM, Lois Foltan <lois.foltan at oracle.com 
>> <mailto:lois.foltan at oracle.com>> wrote:
>>
>>>
>>> On 8/27/2013 7:31 AM, David Holmes wrote:
>>>> On 27/08/2013 6:01 PM, Mikael Gerdin wrote:
>>>>> On 2013-08-27 04:41, David Holmes wrote:
>>>>>> On 27/08/2013 4:36 AM, Lois Foltan wrote:
>>>>>>> Please review the following fix:
>>>>>>>
>>>>>>> Internal webrev:
>>>>>>>
>>>>>>> http://cr.openjdk.java.net/~coleenp/bug_jdk8021954/
>>>>>>>
>>>>>>> Bug: VM SIGSEGV during classloading on MacOS; hs_err_pid file 
>>>>>>> produced &
>>>>>>>           runtime/6878713/Test6878713.sh fails on mac
>>>>>>>
>>>>>>>      bug links at: https://bugs.openjdk.java.net/browse/JDK-8021954
>>>>>>> https://bugs.openjdk.java.net/browse/JDK-8022140
>>>>>>>
>>>>>>> Summary of fix:
>>>>>>>      On MacOS, currently Hotspot is built specifying the 
>>>>>>> -fcheck-new
>>>>>>> command line option to the llvm-g++ compiler.
>>>>>>>      The -fcheck-new option directs the compiler to "check that the
>>>>>>> pointer returned by |operator new| is non-null
>>>>>>>       before attempting to modify the storage allocated."  The 
>>>>>>> clang++
>>>>>>> compiler does not support the
>>>>>>>       -fcheck-new option.  To obtain similiar functionality when
>>>>>>> building Hotspot with clang++, empty exception
>>>>>>>       throw() specifications must be added to all user-defined 
>>>>>>> operator
>>>>>>> new()'s.
>>>>>>
>>>>>> We just spotted something related in the PPC64 port and were 
>>>>>> going the
>>>>>> other way or removing these "spurious" throw() declarations.
>>>>>>
>>>>>> But this seems really ugly - is there really a need to specialize 
>>>>>> this
>>>>>> for clang and use NOEXCEPT to hide it? Shouldn't all C++ compilers
>>>>>> honour the nothrow() semantics?
>>>>>>
>>>>>> That said I thought we already handled this using the "const
>>>>>> std::nothrow_t&  nothrow_constant" where needed? Our other 
>>>>>> operator new
>>>>>> implementations shouldn't return NULL but will abort.
>>>>>>
>>>>>> So why do we need -fcheck-new or this empty throw() ?
>>>>>
>>>>> I guess that if the C++ compiler knows that operator new() will 
>>>>> throw an
>>>>> exception if an allocation fails then it doesn't need to emit code to
>>>>> explicitly avoid calling the constructor.
>>>>
>>>> Yes that is what happens, but why do _we_ need it when ...
>>>>
>>>>> If we declare operator new() with an empty throw() we will also 
>>>>> inform
>>>>> the compiler that new can't throw an exception and therefore the
>>>>> compiler needs to explicitly handle failed allocations.
>>>>
>>>> ... we have two kinds of operator new implementations (or at least 
>>>> we _should_ only have two kinds):
>>>>
>>>> 1. Will abort on OOM (either ResourceArea exhaustion or Stack 
>>>> exhaustion) and so never returns NULL
>>>> 2. Can return NULL and uses std::nothrow to indicate that
>>>>
>>>> So we should not need this if the nothrow is acting as I think it 
>>>> should. Have we missed places where nothrow is needed? Do we have 
>>>> errant operator new definitions unrelated to the allocation base 
>>>> classes?
>>> Hi David,
>>>
>>> I think there may be some confusion about what std::nothrow_t is 
>>> actually doing.  It provides a mechanism to overload operator new & 
>>> delete in order to direct the compiler to prefer a function 
>>> definition that also should contain an empty "throw()" 
>>> specification.  Take for example the standard definition of the 
>>> global ::operator new().  It actually looks like:
>>>
>>>   * void * operator new
>>>     <x-msg://14159/a00960.html#a1414bcdb34c39ce82fc84bc8d5287966>
>>>     (std::size_t) throw (std::bad_alloc)
>>>   * void * operator new
>>>     <x-msg://14159/a00960.html#a940b606c7824b4d5dd121199c277d629>
>>>     (std::size_t, const std::nothrow_t &) throw ()
>>>
>>> When the std::nothrow_t parameter is passed to the global ::operator 
>>> new() the invoked function is the one that also contains an empty 
>>> throw() specification.  It is due to this empty throw() 
>>> specification that directs or triggers the C++ compiler to generate 
>>> the detection of NULL constructor prologue.   Specifying only the 
>>> std::nothrow_t parameter to a class member user-defined ::operator 
>>> new() does not indicate to a C++ compiler that the function does not 
>>> throw an exception.  According to the c++98 standard, a function 
>>> that will throw no exceptions should be delcared with an empty 
>>> "throw()" list specification.  When first experimenting with a fix, 
>>> I did just try to overload Hotspot's user-defined operator new() 
>>> with the std:nothrow_t parameter.  As expected, the mere presence of 
>>> this parameter did not trigger the clang++ compiler to generate NULL 
>>> detection constructor prologue code. Unfortunately, probably due to 
>>> legacy code, some C++ compilers behave differently.  For example, I 
>>> did confirm with Solaris C++ development, the Solaris C++ by default 
>>> always generates constructor prologue code that detects NULL for 
>>> class member user-defined operator new() even in a throw situation.  
>>> G++ provides the -fcheck-new command line option.  It is due to 
>>> these differences of behavior or Hotspot's build specification of 
>>> -fcheck-new that has led us to believe that std::nothrow_t was 
>>> providing something that it is not.
>>>
>>> That said, I would also prefer what you propose, deciding on two 
>>> kinds of operator new()'s that can be defined.  I did examine all of 
>>> the user-defined operator new()'s within the code and I determined 
>>> that only a very small number possibly could not return NULL.  Given 
>>> this, factored in with the historical reliance on -fcheck-new for 
>>> the g++ compilers, I decided the safe route for JDK 8 was to 
>>> introduce the NOEXCEPT macro.
>>
>> Why can't we use throw() with all compilers?  Just because we are 
>> using -fcheck-new for GCC?
> Hi Chris,
>
> Yes certainly that would be preferable to the NOEXCEPT macro.  I also 
> believe most modern C++ compilers support the c++98 standard at this 
> point and would handle the empty throw() specification correctly.  
> However, after discussing with Coleen, it was thought that in order to 
> limit the scope of this change for JDK 8 introducing the NOEXCEPT 
> macro was again the safer route.
>


The NOEXCEPT macro isn't less code changes and the empty throw() would 
probably work, but there's a new c++11 keyword "noexcept" that we might 
need in the future for this behavior.   So the macro enables changing it 
to that for compilers that support it.  That was our thinking at least.

Coleen

> Thanks,
> Lois
>
>>
>> -- Chris
>>
>>>
>>> Lois
>>>>
>>>> David
>>>> -----
>>>>
>>>>> The g++ man page states:
>>>>>
>>>>>         -fcheck-new
>>>>>             Check that the pointer returned by "operator new" is
>>>>> non-null before attempting to modify the storage allocated.  This 
>>>>> check
>>>>> is normally unnecessary because the C++ standard specifies that
>>>>>             "operator new" will only return 0 if it is declared 
>>>>> throw(),
>>>>> in which case the compiler will always check the return value even
>>>>> without this option.  In all other cases, when "operator new"
>>>>>             has a non-empty exception specification, memory 
>>>>> exhaustion
>>>>> is signalled by throwing "std::bad_alloc".  See also new (nothrow).
>>>>>
>>>>> /Mikael
>>>>>
>>>>>>
>>>>>> Thanks,
>>>>>> David
>>>>>>
>>>>>>> Tests:
>>>>>>>
>>>>>>>       Solaris: built fastdebug & product images
>>>>>>>       Linux: built fastdebug & product images
>>>>>>>       MacOS:  built fastdebug & product images using llvm-g++ - ran
>>>>>>> JTREG
>>>>>>>                      built fastdebug & product images using 
>>>>>>> clang++ -
>>>>>>> ran JTREG, JCK vm & lang, vm.quick.testlist (in progress)
>>>>>>>       Windows:  built fastdebug & product images with VS2010
>>>>>>>
>>>
>>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/attachments/20130827/2a37e602/attachment-0001.html 


More information about the hotspot-runtime-dev mailing list