JDK-8043538 : assert(o->is_oop_or_null()) failed: should always be an oop, at heapDumper.cpp:724
  • Type: Bug
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: 8,9
  • Priority: P5
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2014-05-20
  • Updated: 2022-05-17
Related Reports
Relates :  
Description
When doing a heap dump with jmap or jcmd an assert can fail in jdk8 and 9.
The assert fails because the heap dumper is trying to inspect an object that is dead.

Unexpected Error
------------------------------------------------------------------------------
Internal Error at heapDumper.cpp:724, pid=27154, tid=139872669280000
assert(o->is_oop_or_null()) failed: should always be an oop

Analysis from Mikael Gerdin:
-------
Object o1 in region r1 points to humongous object o2 in r2.
o1 and o2 are not reachable.
r2 is freed and later re-used for some other purpose.
(since o2 is not evacuated the reference from o1 is not updated)
r1 is considered expensive to evacuate and is kept around.

A heap dump is requested, which performs object_iterate on all in-use regions.
object_iterate provides a callback to the HeapDumper for each object, dead or 
alive.

The HeapDumper iterates over all the fields of the object and at this point 
o1's reference field which used to point to o2 can now point to arbitrary heap 
memory.
--------

Loading and decoding the oop is fine, but the assert will fail.
In product builds nothing bad will happen, except that the hprof file will have a strange pointer in it.
Comments
Defering this to tbd_major since it is not a problem in production.
13-11-2017

We should probably just remove the if (ClassUnloadingWithConcurrentMark) check around is_obj_dead in HeapRegion::block_is_obj. It seems weird that G1 should allow code iterate over dead objects even though the Klass* is safe to read.
13-11-2017