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

Christian Thalinger christian.thalinger at oracle.com
Tue Aug 27 10:49:12 PDT 2013


On Aug 27, 2013, at 5:44 AM, Lois Foltan <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 (std::size_t) throw (std::bad_alloc)
> void * operator new (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?

-- 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/0f15eaed/attachment.html 


More information about the hotspot-runtime-dev mailing list