JDK-8151546 : nsk/jvmti/RedefineClasses/StressRedefine fails in hs nightly
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2016-03-09
  • Updated: 2017-08-17
  • Resolved: 2016-04-14
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.
JDK 9
9 b116Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
nsk/jvmti/RedefineClasses/StressRedefine fails in hs nightly; log file contains multiple "the function returned error 60: JVMTI_ERROR_INVALID_CLASS_FORMAT"
Comments
It looks like two threads are merging the constant pool for the class. One adds an entry for the new name but the other one doesn't. The latter one overwrites the "merged" constant pool in the original class and the source file name is gone. I don't see anything in class redefinition to handle parallel merging constant pools. Adding an assert assert(scratch_class->constants()->version() == the_class->constants()->version() + 1) in redefine_single_class (during the safepoint) hits immediately for this test. I think this is triggered because many of the entries for invokedynamic don't match in the old constant pool so are added. The constant pool gets quite large.
31-03-2016

The class file corruptor changes the class's source_file_name to MyClass*java so merging constant pool code creates a new constant pool entry in the merged constant pool with the new name, except then it's overwritten on the next redefinition with an invokedynamic.
30-03-2016

Reproduced this on my desktop, linux x64 fastdebug: (gdb) print which $1 = 707 (gdb) print _tags->_data[707] $2 = 18 '\022' <= InvokeDynamic All the other _previous_versions source_file_name_index is 59. (gdb) print holder->_previous_versions->_constants->_tags->_data[59] $8 = 1 '\001' <= Utf8
30-03-2016

More crash symptoms.
15-03-2016

The crash is in the code (dbx not much help but disassembling works). // Fill in source file name and line number. Symbol* source = Backtrace::get_source_file_name(holder, version); Which didn't change with the Reduce Throwable.getStackTrace() calls to the vm change. Serguei is looking through the change again to confirm. Given that there is bytecode corruption in this test, I can't reproduce this error, this test has several failure modes, there is no apparent breakage because of the latest change, and I plan to simplify this code with the linked bug, I don't think this should be an integration blocker.
15-03-2016

Linked to fix that might have caused this.
14-03-2016

This test corrupts class files while it redefines them, so the exception error messages are expected. It sometimes times out because redefinition is slow on some slower machines. The failure RULE "nsk/jvmti/RedefineClasses/StressRedefine" Crash Internal Error ...constantPool.hpp...assert(tag_at(which).is_utf8()) failed: Corrupted constant pool Is a real failure, which is either caused by corrupting the class file or something in the stack trace handling that is broken.
14-03-2016