RFR: 8278602: CDS dynamic dump may access unloaded classes
Coleen Phillimore
coleenp at openjdk.java.net
Thu Dec 16 17:54:00 UTC 2021
On Thu, 16 Dec 2021 03:46:10 GMT, Ioi Lam <iklam at openjdk.org> wrote:
> Cause of crash:
>
> When dumping a CDS archive, while iterating over entries of the `SystemDictionaryShared::_dumptime_table`, we do not check whether the classes are already unloaded. In the crash, we are trying to call `InstanceKlass::signer()` but the class has already been unloaded.
>
> Fix:
>
> Override the template function `DumpTimeSharedClassTable::iterate` to ensure iteration safety. Do not iterate over a class if its `class_loader_data` is no longer alive.
>
> The assert in `DumpTimeSharedClassTable::IterationHelper` found another existing bug -- we were calling `SystemDictionaryShared::is_dumptime_table_empty()` without holding the `DumpTimeTable_lock`. I delayed the call until we have grabbed the lock.
>
> Testing:
>
> I have attached a test case into the bug report. Without the fix, it would reproduce the same crash in less than a minute. With the fix, the crash is no longer reproducible.
>
> Unfortunately, the test case requires a ZGC patch (thanks to @stefank) that adds delays to increase the likelihood of seeing unloaded classes inside the `_dumptime_table`. Therefore, I cannot integrate the test as a jtreg test. I'll mark the bug as **noreg-hard**
Could you also add your unloads a lot test even though it doesn't reproduce this particular error without the ZGC change? It might find a similar bug under stress conditions.
src/hotspot/share/cds/dumpTimeClassInfo.inline.hpp line 53:
> 51: assert_lock_strong(DumpTimeTable_lock);
> 52: if (k->is_loader_alive()) {
> 53: assert(k->is_loader_alive(), "must be");
This does seem a bit paranoid and redundant here.
src/hotspot/share/cds/dumpTimeClassInfo.inline.hpp line 58:
> 56: return result;
> 57: } else {
> 58: if (!SystemDictionaryShared::is_excluded_class(k)) {
I thought this was the original bug? is_excluded_class() looks at mirror->signers() which if the class isn't alive, mirror->signers() will crash. This has to be in the k->is_loader_alive() too.
-------------
Changes requested by coleenp (Reviewer).
PR: https://git.openjdk.java.net/jdk/pull/6859
More information about the hotspot-dev
mailing list