RFR 8243572: Multiple tests fail with assert(cld->klasses() != 0LL) failed: unexpected NULL for cld->klasses()
Harold Seigel
harold.seigel at oracle.com
Wed Apr 29 13:40:23 UTC 2020
Hi David,
Please see inline comments.
On 4/29/2020 12:01 AM, David Holmes wrote:
> Hi Harold,
>
> Not a review ...
>
> On 29/04/2020 3:27 am, Harold Seigel wrote:
>> Hi,
>>
>> Please review this fix for JDK-8243572 and JDK-8243336. Both
>> failures were caused by calling function ClassLoaderData::klasses()
>> and expecting a non-null return value. However, when the CLD had no
>> classes then NULL was returned causing the assertion failure in one
>> case and SIGSEGV in the other.
>>
>> Function klasses() was called in these places to determine if the
>> ClassLoaderData was for a hidden class or an unsafe anonymous class.
>> This was done during CLD statistics collection and for JFR events
>> involving CLD's.
>>
>> Since the JDK has replaced uses of unsafe anonymous classes with
>> hidden classes, there should be very few unsafe anonymous classes.
>> So, it was decided (with mgronlun and mchung) that the VM and JFR
>> need no longer distinguish between hidden and unsafe anonymous
>> classes when gathering CLD statistics and when CLD's are displayed in
>> JFR events. Instead, unsafe anonymous classes will be counted as
>> hidden classes for CLD statistics, and JFR will show CLD's for both
>> hidden and unsafe anonymous classes as hidden.
>
> Okay, but putting aside the decision to no longer distinguish between
> old VM unsafe anonymous classes and new hidden classes, what was the
> actual source of the failure here? The CLD has no classes, but what
> code was expecting to find classes and why? Was it just an oversight
> with the new hidden classes code?
It's a bug in the new hidden classes code. The problem is in two
different places, in ClassLoaderStatsClosure::do_cld() and in
MetaspaceTracer::send_allocation_failure_event(). Both functions call
ClassLoaderData::klasses() and expect the result to be non-null. The
former case gets a SIGSEGV because it dereferences the result. The
latter case asserts if the result is null. These calls to
ClassLoaderData::klasses() were added as part of the hidden classes
implementation.
The SIGSEGV occurs when the VM is creating a hidden or unsafe anonymous
class. It creates a special ClassLoaderData and adds it to the
ClassLoaderDataGraph before loading the class. If statistics collection
occurs between the time it creates the CLD and loads the class, then the
CLD will not have any classes and the new call to
ClassLoaderData::klasses() will return NULL, eventually causing the SIGSEGV.
The MetaspaceTracer::send_allocation_failure_event() assert happens when
classFileParser has created the special ClassLoaderData for the hidden
class but then runs out of metaspace when trying to load the hidden
class. If JFR is enabled then the JVM tries to create an allocation
failure event by calling send_allocation_failure_event(), causing the
assertion failure.
I hope this is helpful.
Thanks, Harold
>
> Thanks,
> David
>
>> Open Webrev:
>> http://cr.openjdk.java.net/~hseigel/bug_8243572/webrev/index.html
>>
>> JBS Bugs: https://bugs.openjdk.java.net/browse/JDK-8243572 and
>> https://bugs.openjdk.java.net/browse/JDK-8243336
>>
>> The fix was regression tested by running Mach5 tiers 1 and 2 tests
>> and builds on Linux-x64, Solaris, Windows, and Mac OS X, by running
>> Mach5 tiers 3-5 tests on Linux-x64, and running tier 7 tests multiple
>> times on Windows and also on Mac OS X. Tier 7 testing on Linux-X64
>> is in progress.
>>
>> Thanks, Harold
>>
More information about the hotspot-runtime-dev
mailing list