JDK-8076110 : VM crash when class is redefined with Instrumentation.redefineClasses
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 8u40,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2015-03-26
  • Updated: 2017-01-10
  • Resolved: 2015-06-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
6-poolResolved 7-poolResolved 8u66Fixed 9 b72Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc:  SuppressErrorAt=/constantPool.cpp:562
# A fatal error has been detected by the Java Runtime Environment:
#  Internal Error (/HUDSON/workspace/9-2-build-linux-amd64/jdk9/2493/hotspot/src/share/vm/oops/constantPool.cpp:562), pid=1717, tid=139782905890560
#  assert(error != __null && message != __null) failed: checking
# JRE version: Java(TM) SE Runtime Environment (9.0-b59) (build 1.9.0-ea-fastdebug-b59)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (1.9.0-ea-fastdebug-b59 interpreted mode linux-amd64 compressed oops)

Suggested release note: The JVM could crash when a class was redefined with Instrumentation.redefineClasses(). The crash could either be a segmentation fault at SystemDictionary::resolve_or_null, or an internal error with the message "tag mismatch with resolution error table". This has now been fixed

Review thread: http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2015-June/014948.html

ConstantPool::deallocate_contents can happen when we are not at safepoint, which means we would have to take the SystemDictionary lock every time a constant pool is deallocated, to remove potentially cached resolution errors. To avoid locks, instead do the deletion of resolution errors when the {add,purge}_previous_version functions has come to the conclusion that the constant pool / resolution errors are not needed since the java methods are not running any more. These functions will only be called during safepoint, either after a class redefinition or when unloading classes.

The crash happens when the redefine occurs while the redefined method is still running. This is because VM_RedefineClasses::redefine_single_class deletes the resolution errors at redefine time, but the running method might still need them. Looks like this can be fixed by moving the delete_resolution_error call to the ConstantPool::deallocate_contents instead, which ensures that the cached resolution_errors are removed only when no method uses the constant pool any more.

Example calls in order: Breakpoint 1, SystemDictionary::delete_resolution_error (pool=0x7fffdfa0b8a0) at /home/aeriksso/sources/jdk9-dev/hotspot/src/share/vm/classfile/systemDictionary.cpp:2166 2166 void SystemDictionary::delete_resolution_error(ConstantPool* pool) { Deleting REs for pool 0x7fffdfa0b8a0 #0 SystemDictionary::delete_resolution_error (pool=0x7fffdfa0b8a0) at /home/aeriksso/sources/jdk9-dev/hotspot/src/share/vm/classfile/systemDictionary.cpp:2166 #1 0x00007ffff5a4942b in VM_RedefineClasses::redefine_single_class (this=0x7fffde8d51c0, the_jclass=0x7fffb8000aa8, scratch_class_oop=0x7c009f630, __the_thread__=0x7ffff00e3000) at /home/aeriksso/sources/jdk9-dev/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp:4089 ... [Switching to Thread 0x7fffde7d5700 (LWP 28361)] Breakpoint 6, SystemDictionary::find_resolution_error (pool=..., which=29, message=0x7fffde7d4020) at /home/aeriksso/sources/jdk9-dev/hotspot/src/share/vm/classfile/systemDictionary.cpp:2172 2172 Symbol** message) { Finding RE from pool 0x7fffdfa0b8a0 #0 SystemDictionary::find_resolution_error (pool=..., which=29, message=0x7fffde7d4020) at /home/aeriksso/sources/jdk9-dev/hotspot/src/share/vm/classfile/systemDictionary.cpp:2172 #1 0x00007ffff5633ef8 in ConstantPool::throw_resolution_error (this_cp=..., which=29, __the_thread__=0x7ffff01b8800) at /home/aeriksso/sources/jdk9-dev/hotspot/src/share/vm/oops/constantPool.cpp:561 #2 0x00007ffff56324b4 in ConstantPool::klass_at_impl (this_cp=..., which=29, save_resolution_error=true, __the_thread__=0x7ffff01b8800) at /home/aeriksso/sources/jdk9-dev/hotspot/src/share/vm/oops/constantPool.cpp:236

Looks like a race between one thread reading a cached resolution error from the system dictionary, and the redefining thread that removes it on class redefinition.