RFR: JDK-8131600: heapdump/JMapHeap EXCEPTION_ACCESS_VIOLATION
Bengt Rutisson
bengt.rutisson at oracle.com
Wed Jul 22 12:12:32 UTC 2015
Hi everyone,
Could I have a couple of reviews for this patch to fix one of the
critical nightly issues we are currently having?
http://cr.openjdk.java.net/~brutisso/8131600/webrev.00/
https://bugs.openjdk.java.net/browse/JDK-8131600
Background
When we load a class we first create the InstanceKlass and then allocate
the Java mirror on the heap. The allocation of the Java mirror is just
like any other allocation, so it can be blocked by a safepoint since it
will in some cases try to take the heap lock.
This means that when we hit a safepoint there can potentially exist
InstanceKlasses where ik->java_mirror() == NULL.
The DumperSupport::dump_class_and_array_classes() currently does not
handle that case. It blindly calls ik->signers() on the klass it is
supposed to dump. signers() looks up the mirror (java_class()) and
passes it on:
objArrayOop InstanceKlass::signers() const {
// return the signers from the mirror
return java_lang_Class::signers(java_mirror());
}
...to java_lang_Class::signers(), which will crash if it gets NULL as
java_class:
objArrayOop java_lang_Class::signers(oop java_class) {
assert(_signers_offset != 0, "must be set");
return (objArrayOop)java_class->obj_field(_signers_offset);
}
The dump_class_and_array_classes() is called as part of dumping the heap
from a jmap call. This is obviously done at a safepoint. So, if the jmap
call comes in between the creation of the InstanceKlass and the
allocation of the mirror we end up calling
dump_class_and_array_classes() with an InstanceKlass that has NULL as
its mirror. This is the reason for the crash in JDK-8131600.
Except for DumperSupport::dump_class_and_array_classes() there is only
one user of InstanceKlass::signers(). That is
VM_HeapWalkOperation::iterate_over_class(). This method has an early
exit if the class has not been properly initialized yet:
// ignore the class if it's has been initialized yet
if (!ik->is_linked()) {
return true;
}
So, I think the proper fix for JDK-8131600 is to make sure that
DumperSupport::dump_class_and_array_classes() has the same check.
Now, DumperSupport::dump_class_and_array_classes() actually calls
InstanceKlass::signers() twice. The second time around we don't have an
InstanceKlass but just a Klass. The Klass does not have the is_linked()
method. I haven't tried to provoke that code to fail, but I assume it
has the same problem. So, I added a java_class() != NULL check to that
code to make it handle this case as well.
Thanks,
Bengt
More information about the hotspot-gc-dev
mailing list