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