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

Lois Foltan lois.foltan at oracle.com
Tue Aug 27 05:44:01 PDT 2013


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 <a00960.html#a1414bcdb34c39ce82fc84bc8d5287966>
    (std::size_t) throw (std::bad_alloc)
  * void * operator new <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.

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/ff53f4c9/attachment-0001.html 


More information about the hotspot-runtime-dev mailing list