JDK-8267810 : CDS dynamic dump corrupts SharedPathTable
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • Submitted: 2021-05-26
  • Updated: 2021-05-26
  • Resolved: 2021-05-26
Related Reports
Duplicate :  
Description
Apply the following patch to call  DynamicArchive::dump() twice:

+++ b/src/hotspot/share/runtime/java.cpp
@@ -511,6 +511,7 @@ void before_exit(JavaThread* thread) {
   if (DynamicDumpSharedSpaces) {
     ExceptionMark em(thread);
     DynamicArchive::dump();
+    DynamicArchive::dump();

$  java -Xlog:cds -cp ~/tmp/HelloWorld.jar -XX:ArchiveClassesAtExit=/tmp/foo.jsa HelloWorld

The following crash happens:
 9 Array<char>::size    =========> this == 0x800c415e0
10 MetaspaceClosure::ArrayRef<char>::size 
11 ArchiveBuilder::gather_klass_and_symbol 
12 GatherKlassesAndSymbols::do_unique_ref 
13 UniqueMetaspaceClosure::do_ref 
14 MetaspaceClosure::do_push 
15 MetaspaceClosure::push_impl 
16 MetaspaceClosure::push_with_ref<MetaspaceClosure::OtherArrayRef<char>, Array<char> > 
17 MetaspaceClosure::push<char, 0> 
18 SharedClassPathEntry::metaspace_pointers_do 
19 SharedPathTable::metaspace_pointers_do 
20 FileMapInfo::metaspace_pointers_do 
21 DynamicArchiveBuilder::iterate_roots 
22 ArchiveBuilder::gather_klasses_and_symbols 
23 ArchiveBuilder::gather_source_objs 
24 DynamicArchiveBuilder::doit 
25 VM_PopulateDynamicDumpSharedSpace::doit 

The problem is that FileMapInfo::_saved_shared_path_table was relocated during the first call to DynamicArchive::dump()
Comments
This bug has no impact as long as we restrict the JVM to do only a single dynamic CDS dump during its process lifetime, which is the case for JDK 17. Closing this as a duplicate of JDK-8264735.
26-05-2021

This doesn't affect the normal execution of a program. We have two SharedPathTables. After "jcmd <pid> VM.cds dynamic_dump" [1] FileMapInfo::_saved_shared_path_table is corrupted [2] FileMapInfo::_shared_path_table is not corrupted. [2] is used during normal execution of the Java program. E.g., it's used by SystemDictionaryShared::get_shared_jar_manifest(). As a result, after the "jcmd ... dynamic_dump" has finished, the Java program can still continue normal execution. In the following program, after jcmd has finished, WaitAndExitXX is loaded from the static shared archive. During the loading of WaitAndExitXX, [2] is used, so the VM works fine without crashing. =======================WaitAndExit.java /* javac WaitAndExit.java jar cf WaitAndExit.jar WaitAndExit.class WaitAndExitXX.class echo WaitAndExitXX > WaitAndExit.classlist java -Xlog:cds -Xshare:dump -cp WaitAndExit.jar -XX:ExtraSharedClassListFile=WaitAndExit.classlist -XX:SharedArchiveFile=WaitAndExit.static.jsa java -cp WaitAndExit.jar -XX:SharedArchiveFile=WaitAndExit.static.jsa -verbose WaitAndExit touch flagfile && \ java -XX:+RecordDynamicDumpInfo -cp WaitAndExit.jar -XX:SharedArchiveFile=WaitAndExit.static.jsa WaitAndExit flagfile & jcmd WaitAndExit VM.cds dynamic_dump rm flagfile */ import java.io.*; public class WaitAndExit { public static void main(String args[]) throws Throwable { if (args.length > 0) { File f = new File(args[0]); while (f.exists()) { Thread.sleep(100); } } WaitAndExitXX.doit(); } } class WaitAndExitXX { static void doit() { System.out.println("I am done"); } } =======================
26-05-2021