Skip to content
Permalink
Browse files
8246382: assert in MetaspaceShared::map_archives
Perform base archive header CRC check earlier.

Reviewed-by: iklam, coleenp
  • Loading branch information
calvinccheung committed Jun 11, 2020
1 parent 212ab17 commit 30ff2ad58c27d4e10aaf8d282ebf1450f1d63a08
Showing 4 changed files with 103 additions and 18 deletions.
@@ -1119,28 +1119,24 @@ DynamicArchiveBuilder* DynamicArchive::_builder = NULL;


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;
}
@@ -2140,7 +2140,14 @@ bool FileMapHeader::validate() {
}

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
@@ -2595,16 +2595,9 @@ MapArchiveResult MetaspaceShared::map_archive(FileMapInfo* mapinfo, char* mapped
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);
@@ -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);
});

}
}

0 comments on commit 30ff2ad

Please sign in to comment.