Crash in ArchiveHeapWriter::compute_ptrmap when archiving heap objects of excluded classes

Anton Voznia avoznia at azul.com
Mon Feb 9 15:24:53 UTC 2026


Hi all,


I have a question about a potential bug in AOT heap archiving.


We observe a crash (guarantee failure) while creating the AOT cache with JDK 25, at:

https://github.com/openjdk/jdk25u-dev/blob/40ec273de548b47fc08d02bbe7c1cb3b48ebad17/src/hotspot/share/cds/archiveHeapWriter.cpp#L757


The failure happens because:

get_buffered_addr(src_addr) == nullptr


What means that a native pointer is present in _native_pointers but there is no corresponding buffered address, even though the SourceObjInfo was successfully added to _src_obj_table.

The failing check is:

guarantee(ArchiveBuilder::current()->has_been_buffered((address)native_ptr),

          "Metadata %p should have been archived", native_ptr);


further investigation showed that we collect pointers into _native_pointers without checking whether the corresponding class was excluded (via class exclusion or link-time verification failures):

https://github.com/openjdk/jdk25u-dev/blob/40ec273de548b47fc08d02bbe7c1cb3b48ebad17/src/hotspot/share/cds/heapShared.cpp#L308


However, the SourceObjInfo::_buffered_addr seems to be assigned only for objects that are actually copied (i.e., not excluded).


In particular, this SourceObjInfo didn’t end up in _ro_src_objs or _rw_src_objs because it didn’t satisfy the following condition:

https://github.com/openjdk/jdk25u-dev/blob/40ec273de548b47fc08d02bbe7c1cb3b48ebad17/src/hotspot/share/cds/archiveBuilder.cpp#L467


  if (created && src_info.should_copy()) {

    if (read_only) {

      _ro_src_objs.append(p);

    } else {

      _rw_src_objs.append(p);

    }

    return true; // Need to recurse into this ref only if we are copying it

  }


created is true (object exists in _src_obj_table), but src_info.should_copy() is false because _follow_mode is set_to_null (not make_a_copy).


So it looks like we may end up with an item in _native_pointers for which we will never assign a buffered address.

However, later we expect every item in _native_pointers to have one buffered address.


Is this logic correct, or am I missing a step that guarantees buffering for all _native_pointers items?

It seems, we have to check for a class exclusion before adding into _native_pointers.


Unfortunately, I wasn’t able to reproduce the issue locally.


Thanks and best regards,
Anton Voznia


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/leyden-dev/attachments/20260209/d03cea05/attachment.htm>


More information about the leyden-dev mailing list