changeset 59744:93813843680b jdk-15+27 jdk-16+0

8246382: assert in MetaspaceShared::map_archives Summary: Perform base archive header CRC check earlier. Reviewed-by: iklam, coleenp
author ccheung
date Thu, 11 Jun 2020 15:47:36 +0000
parents da0c90391866
children 16081904714f 1242c6a84642
files src/hotspot/share/memory/dynamicArchive.cpp src/hotspot/share/memory/filemap.cpp src/hotspot/share/memory/metaspaceShared.cpp test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MismatchedBaseArchive.java
diffstat 4 files changed, 103 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/memory/dynamicArchive.cpp	Wed Jun 10 13:17:03 2020 +0200
+++ b/src/hotspot/share/memory/dynamicArchive.cpp	Thu Jun 11 15:47:36 2020 +0000
@@ -1119,28 +1119,24 @@
 
 
 bool DynamicArchive::validate(FileMapInfo* dynamic_info) {
+  assert(!dynamic_info->is_static(), "must be");
   // Check if the recorded base archive matches with the current one
   FileMapInfo* base_info = FileMapInfo::current_info();
   DynamicArchiveHeader* dynamic_header = dynamic_info->dynamic_header();
 
   // Check the header crc
   if (dynamic_header->base_header_crc() != base_info->crc()) {
-    FileMapInfo::fail_continue("Archive header checksum verification failed.");
+    FileMapInfo::fail_continue("Dynamic archive cannot be used: static archive header checksum verification failed.");
     return false;
   }
 
   // Check each space's crc
   for (int i = 0; i < MetaspaceShared::n_regions; i++) {
     if (dynamic_header->base_region_crc(i) != base_info->space_crc(i)) {
-      FileMapInfo::fail_continue("Archive region #%d checksum verification failed.", i);
+      FileMapInfo::fail_continue("Dynamic archive cannot be used: static archive region #%d checksum verification failed.", i);
       return false;
     }
   }
 
-  // Validate the dynamic archived shared path table, and set the global
-  // _shared_path_table to that.
-  if (!dynamic_info->validate_shared_path_table()) {
-    return false;
-  }
   return true;
 }
--- a/src/hotspot/share/memory/filemap.cpp	Wed Jun 10 13:17:03 2020 +0200
+++ b/src/hotspot/share/memory/filemap.cpp	Thu Jun 11 15:47:36 2020 +0000
@@ -2140,7 +2140,14 @@
 }
 
 bool FileMapInfo::validate_header() {
-  return header()->validate();
+  if (!header()->validate()) {
+    return false;
+  }
+  if (_is_static) {
+    return true;
+  } else {
+    return DynamicArchive::validate(this);
+  }
 }
 
 // Check if a given address is within one of the shared regions
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Wed Jun 10 13:17:03 2020 +0200
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Thu Jun 11 15:47:36 2020 +0000
@@ -2595,16 +2595,9 @@
     return result;
   }
 
-  if (mapinfo->is_static()) {
-    if (!mapinfo->validate_shared_path_table()) {
-      unmap_archive(mapinfo);
-      return MAP_ARCHIVE_OTHER_FAILURE;
-    }
-  } else {
-    if (!DynamicArchive::validate(mapinfo)) {
-      unmap_archive(mapinfo);
-      return MAP_ARCHIVE_OTHER_FAILURE;
-    }
+  if (!mapinfo->validate_shared_path_table()) {
+    unmap_archive(mapinfo);
+    return MAP_ARCHIVE_OTHER_FAILURE;
   }
 
   mapinfo->set_is_mapped(true);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MismatchedBaseArchive.java	Thu Jun 11 15:47:36 2020 +0000
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @summary The base archive used for dynamic dump is not the same as the one
+ *          used during run time. With -Xshare:on, VM will exit with en error message.
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes
+ * @build Hello
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller -jar hello.jar Hello
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. MismatchedBaseArchive
+ */
+
+public class MismatchedBaseArchive extends DynamicArchiveTestBase {
+    public static void main(String[] args) throws Exception {
+        createBaseArchive();
+        runTest(MismatchedBaseArchive::testDefaultBase);
+        runTest(MismatchedBaseArchive::testCustomBase);
+    }
+
+    static String helloBaseArchive = getNewArchiveName("base-with-hello");
+    static String appJar = ClassFileInstaller.getJarPath("hello.jar");
+    static String mainClass = "Hello";
+
+    static void createBaseArchive() throws Exception {
+        TestCommon.dumpBaseArchive(helloBaseArchive,
+                                   "-Xlog:cds",
+                                   "-cp", appJar, mainClass);
+    }
+
+    // (1) Test with default base archive + top archive
+    static void testDefaultBase() throws Exception {
+        String topArchiveName = getNewArchiveName("top");
+        doTest(null, topArchiveName);
+    }
+
+    // (2) Test with custom base archive + top archive
+    static void testCustomBase() throws Exception {
+        String topArchiveName = getNewArchiveName("top2");
+        String baseArchiveName = getNewArchiveName("base");
+        TestCommon.dumpBaseArchive(baseArchiveName);
+        doTest(baseArchiveName, topArchiveName);
+    }
+
+    private static void doTest(String baseArchiveName, String topArchiveName) throws Exception {
+        dump2(baseArchiveName, topArchiveName,
+             "-Xlog:cds",
+             "-Xlog:cds+dynamic=debug",
+             "-cp", appJar, mainClass)
+            .assertNormalExit(output -> {
+                    output.shouldContain("Buffer-space to target-space delta")
+                           .shouldContain("Written dynamic archive 0x");
+                });
+
+        run2(helloBaseArchive, topArchiveName,
+            "-Xlog:class+load",
+            "-Xlog:cds+dynamic=debug,cds=debug",
+            "-cp", appJar, mainClass)
+            .assertAbnormalExit(output -> {
+                    output.shouldContain("Dynamic archive cannot be used: static archive header checksum verification failed.")
+                          .shouldHaveExitValue(1);
+                });
+
+    }
+}