RFR: 8365526: Crash with null Symbol passed to SystemDictionary::resolve_or_null

Coleen Phillimore coleenp at openjdk.org
Fri Nov 21 18:43:29 UTC 2025


On Fri, 21 Nov 2025 17:10:29 GMT, Tom Rodriguez <never at openjdk.org> wrote:

>> The vm was crashing because the constant pool couldn't find the resolution error in the ResolutionErrorEntry error field.
>> 
>> There are two uses of ResolutionErrorEntry in the ResolutionErrorTable.  The key to this table is {ConstantPool, cp-index}.   In this crash, multiple threads were racing to record nest_host_errors in the case where resolution failed.  In this case, there was already a ResolutionErrorEntry in the table for the constant pool resolution failure.  In the 'if' case of add_nest_host_error we check to see if there's already a nest_host_error assuming it's the same error, then the 'else' case was unconditionally adding a ResolutionErrorEntry with just the nest host message.  Calling HashTable::put() with this entry with just the nest host message, was overwriting the entry with the constant pool resolution error, ie. the other fields.  The crash happened in ConstantPool::throw_resolution_error() because the error field was overwritten (and leaked too).
>> 
>> Add a null check before calling ResolutionErrorEntry add entry.  Also added an assert that we only add a resolution error for nest host errors in the case of success since in the case of failure there will always already be a ResolutionErrorEntry for the failing constant pool and cp index and we don't want to overwrite that again.
>> 
>> Tested with submitted reproducer and tier1-4.
>
> src/hotspot/share/classfile/systemDictionary.cpp line 1877:
> 
>> 1875:       // resolution succeeded but there's an error in this nest host.
>> 1876:       assert(pool->resolved_klass_at(which) != nullptr, "klass is should be resolved if there is no entry");
>> 1877:       ResolutionErrorTable::add_entry(pool, which, message);
> 
> I might be inclined to swap the cases.
> 
> if (entry == nullptr) {
>     ...
> } else if (entry->nest_host_error() == nullptr) {
>     ...
> }
> 
> 
> Is there ever a situation where replacing an entry in ResolutionErrorTable is correct?  Maybe there should be a check for that somewhere?

Yes, this reorganization would look nicer.
No, there's a never a situation where calling replacing an entry in the ResolutionErrorTable is correct because this HashTable::put() function leaks the value that it has replaced.  I've been testing an assert for this.
In general, this function can leak the value but I did a test and we don't leak anything but this one right now.  But I think we should fix this separately.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/28438#discussion_r2550655223


More information about the hotspot-runtime-dev mailing list