Skip to content

Commit 620f816

Browse files
committed
8327495: Print more warning with -Xshare:auto when CDS fails to use archive
Reviewed-by: iklam, matsaave
1 parent 6bcbc3b commit 620f816

File tree

12 files changed

+99
-50
lines changed

12 files changed

+99
-50
lines changed

src/hotspot/share/cds/aotClassLocation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,7 @@ bool AOTClassLocationConfig::validate(bool has_aot_linked_classes, bool* has_ext
10301030
}
10311031
} else {
10321032
log_warning(cds)("%s%s", mismatch_msg, hint_msg);
1033+
MetaspaceShared::report_loading_error(nullptr);
10331034
}
10341035
}
10351036
return success;

src/hotspot/share/cds/cdsConfig.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,14 @@ bool CDSConfig::is_using_archive() {
647647
return UseSharedSpaces;
648648
}
649649

650+
bool CDSConfig::is_using_only_default_archive() {
651+
return is_using_archive() &&
652+
input_static_archive_path() != nullptr &&
653+
default_archive_path() != nullptr &&
654+
strcmp(input_static_archive_path(), default_archive_path()) == 0 &&
655+
input_dynamic_archive_path() == nullptr;
656+
}
657+
650658
bool CDSConfig::is_logging_lambda_form_invokers() {
651659
return ClassListWriter::is_enabled() || is_dumping_dynamic_archive();
652660
}

src/hotspot/share/cds/cdsConfig.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class CDSConfig : public AllStatic {
103103

104104
// input archive(s)
105105
static bool is_using_archive() NOT_CDS_RETURN_(false);
106+
static bool is_using_only_default_archive() NOT_CDS_RETURN_(false);
106107

107108
// static_archive
108109
static bool is_dumping_static_archive() { return CDS_ONLY(_is_dumping_static_archive) NOT_CDS(false); }

src/hotspot/share/cds/filemap.cpp

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ bool FileMapInfo::validate_class_location() {
326326

327327
if (header()->has_full_module_graph() && has_extra_module_paths) {
328328
CDSConfig::stop_using_optimized_module_handling();
329-
log_info(cds)("optimized module handling: disabled because extra module path(s) are specified");
329+
MetaspaceShared::report_loading_error("optimized module handling: disabled because extra module path(s) are specified");
330330
}
331331

332332
if (CDSConfig::is_dumping_dynamic_archive()) {
@@ -1256,7 +1256,7 @@ char* FileMapInfo::map_bitmap_region() {
12561256
char* bitmap_base = map_memory(_fd, _full_path, r->file_offset(),
12571257
requested_addr, r->used_aligned(), read_only, allow_exec, mtClassShared);
12581258
if (bitmap_base == nullptr) {
1259-
log_info(cds)("failed to map relocation bitmap");
1259+
MetaspaceShared::report_loading_error("failed to map relocation bitmap");
12601260
return nullptr;
12611261
}
12621262

@@ -1454,9 +1454,9 @@ void FileMapInfo::map_or_load_heap_region() {
14541454
success = ArchiveHeapLoader::load_heap_region(this);
14551455
} else {
14561456
if (!UseCompressedOops && !ArchiveHeapLoader::can_map()) {
1457-
log_info(cds)("Cannot use CDS heap data. Selected GC not compatible -XX:-UseCompressedOops");
1457+
MetaspaceShared::report_loading_error("Cannot use CDS heap data. Selected GC not compatible -XX:-UseCompressedOops");
14581458
} else {
1459-
log_info(cds)("Cannot use CDS heap data. UseEpsilonGC, UseG1GC, UseSerialGC, UseParallelGC, or UseShenandoahGC are required.");
1459+
MetaspaceShared::report_loading_error("Cannot use CDS heap data. UseEpsilonGC, UseG1GC, UseSerialGC, UseParallelGC, or UseShenandoahGC are required.");
14601460
}
14611461
}
14621462
}
@@ -1468,8 +1468,10 @@ void FileMapInfo::map_or_load_heap_region() {
14681468
// all AOT-linked classes are visible.
14691469
//
14701470
// We get here because the heap is too small. The app will fail anyway. So let's quit.
1471-
MetaspaceShared::unrecoverable_loading_error("CDS archive has aot-linked classes but the archived "
1472-
"heap objects cannot be loaded. Try increasing your heap size.");
1471+
log_error(cds)("%s has aot-linked classes but the archived "
1472+
"heap objects cannot be loaded. Try increasing your heap size.",
1473+
CDSConfig::type_of_archive_being_loaded());
1474+
MetaspaceShared::unrecoverable_loading_error();
14731475
}
14741476
CDSConfig::stop_using_full_module_graph("archive heap loading failed");
14751477
}
@@ -1635,7 +1637,7 @@ bool FileMapInfo::map_heap_region_impl() {
16351637
// allocate from java heap
16361638
HeapWord* start = G1CollectedHeap::heap()->alloc_archive_region(word_size, (HeapWord*)requested_start);
16371639
if (start == nullptr) {
1638-
log_info(cds)("UseSharedSpaces: Unable to allocate java heap region for archive heap.");
1640+
MetaspaceShared::report_loading_error("UseSharedSpaces: Unable to allocate java heap region for archive heap.");
16391641
return false;
16401642
}
16411643

@@ -1670,7 +1672,7 @@ bool FileMapInfo::map_heap_region_impl() {
16701672

16711673
if (VerifySharedSpaces && !r->check_region_crc(base)) {
16721674
dealloc_heap_region();
1673-
log_info(cds)("UseSharedSpaces: mapped heap region is corrupt");
1675+
MetaspaceShared::report_loading_error("UseSharedSpaces: mapped heap region is corrupt");
16741676
return false;
16751677
}
16761678
}
@@ -1694,7 +1696,7 @@ bool FileMapInfo::map_heap_region_impl() {
16941696
if (_heap_pointers_need_patching) {
16951697
char* bitmap_base = map_bitmap_region();
16961698
if (bitmap_base == nullptr) {
1697-
log_info(cds)("CDS heap cannot be used because bitmap region cannot be mapped");
1699+
MetaspaceShared::report_loading_error("CDS heap cannot be used because bitmap region cannot be mapped");
16981700
dealloc_heap_region();
16991701
_heap_pointers_need_patching = false;
17001702
return false;
@@ -1807,16 +1809,16 @@ bool FileMapInfo::open_as_input() {
18071809
// are replaced at runtime by JVMTI ClassFileLoadHook. All of those classes are resolved
18081810
// during the JVMTI "early" stage, so we can still use CDS if
18091811
// JvmtiExport::has_early_class_hook_env() is false.
1810-
log_info(cds)("CDS is disabled because early JVMTI ClassFileLoadHook is in use.");
1812+
MetaspaceShared::report_loading_error("CDS is disabled because early JVMTI ClassFileLoadHook is in use.");
18111813
return false;
18121814
}
18131815

18141816
if (!open_for_read() || !init_from_file(_fd) || !validate_header()) {
18151817
if (_is_static) {
1816-
log_info(cds)("Loading static archive failed.");
1818+
MetaspaceShared::report_loading_error("Loading static archive failed.");
18171819
return false;
18181820
} else {
1819-
log_info(cds)("Loading dynamic archive failed.");
1821+
MetaspaceShared::report_loading_error("Loading dynamic archive failed.");
18201822
if (AutoCreateSharedArchive) {
18211823
CDSConfig::enable_dumping_dynamic_archive(_full_path);
18221824
}
@@ -1831,29 +1833,34 @@ bool FileMapInfo::validate_aot_class_linking() {
18311833
// These checks need to be done after FileMapInfo::initialize(), which gets called before Universe::heap()
18321834
// is available.
18331835
if (header()->has_aot_linked_classes()) {
1836+
const char* archive_type = CDSConfig::type_of_archive_being_loaded();
18341837
CDSConfig::set_has_aot_linked_classes(true);
18351838
if (JvmtiExport::should_post_class_file_load_hook()) {
1836-
log_error(cds)("CDS archive has aot-linked classes. It cannot be used when JVMTI ClassFileLoadHook is in use.");
1839+
log_error(cds)("%s has aot-linked classes. It cannot be used when JVMTI ClassFileLoadHook is in use.",
1840+
archive_type);
18371841
return false;
18381842
}
18391843
if (JvmtiExport::has_early_vmstart_env()) {
1840-
log_error(cds)("CDS archive has aot-linked classes. It cannot be used when JVMTI early vm start is in use.");
1844+
log_error(cds)("%s has aot-linked classes. It cannot be used when JVMTI early vm start is in use.",
1845+
archive_type);
18411846
return false;
18421847
}
18431848
if (!CDSConfig::is_using_full_module_graph()) {
1844-
log_error(cds)("CDS archive has aot-linked classes. It cannot be used when archived full module graph is not used.");
1849+
log_error(cds)("%s has aot-linked classes. It cannot be used when archived full module graph is not used.",
1850+
archive_type);
18451851
return false;
18461852
}
18471853

18481854
const char* prop = Arguments::get_property("java.security.manager");
18491855
if (prop != nullptr && strcmp(prop, "disallow") != 0) {
1850-
log_error(cds)("CDS archive has aot-linked classes. It cannot be used with -Djava.security.manager=%s.", prop);
1856+
log_error(cds)("%s has aot-linked classes. It cannot be used with -Djava.security.manager=%s.",
1857+
archive_type, prop);
18511858
return false;
18521859
}
18531860

18541861
#if INCLUDE_JVMTI
18551862
if (Arguments::has_jdwp_agent()) {
1856-
log_error(cds)("CDS archive has aot-linked classes. It cannot be used with JDWP agent");
1863+
log_error(cds)("%s has aot-linked classes. It cannot be used with JDWP agent", archive_type);
18571864
return false;
18581865
}
18591866
#endif
@@ -1913,8 +1920,8 @@ bool FileMapHeader::validate() {
19131920
const char* prop = Arguments::get_property("java.system.class.loader");
19141921
if (prop != nullptr) {
19151922
if (has_aot_linked_classes()) {
1916-
log_error(cds)("CDS archive has aot-linked classes. It cannot be used when the "
1917-
"java.system.class.loader property is specified.");
1923+
log_error(cds)("%s has aot-linked classes. It cannot be used when the "
1924+
"java.system.class.loader property is specified.", CDSConfig::type_of_archive_being_loaded());
19181925
return false;
19191926
}
19201927
log_warning(cds)("Archived non-system classes are disabled because the "

src/hotspot/share/cds/metaspaceShared.cpp

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@ void MetaspaceShared::preload_and_dump_impl(StaticArchiveBuilder& builder, TRAPS
937937
if (CDSConfig::is_dumping_heap()) {
938938
assert(CDSConfig::allow_only_single_java_thread(), "Required");
939939
if (!HeapShared::is_archived_boot_layer_available(THREAD)) {
940-
log_info(cds)("archivedBootLayer not available, disabling full module graph");
940+
report_loading_error("archivedBootLayer not available, disabling full module graph");
941941
CDSConfig::stop_dumping_full_module_graph();
942942
}
943943
// Do this before link_shared_classes(), as the following line may load new classes.
@@ -1118,10 +1118,7 @@ bool MetaspaceShared::is_shared_static(void* p) {
11181118
// - When -XX:+RequireSharedSpaces is specified, AND the JVM cannot load the archive(s) due
11191119
// to version or classpath mismatch.
11201120
void MetaspaceShared::unrecoverable_loading_error(const char* message) {
1121-
log_error(cds)("An error has occurred while processing the %s.", CDSConfig::type_of_archive_being_loaded());
1122-
if (message != nullptr) {
1123-
log_error(cds)("%s", message);
1124-
}
1121+
report_loading_error(message);
11251122

11261123
if (CDSConfig::is_dumping_final_static_archive()) {
11271124
vm_exit_during_initialization("Must be a valid AOT configuration generated by the current JVM", AOTConfiguration);
@@ -1132,6 +1129,30 @@ void MetaspaceShared::unrecoverable_loading_error(const char* message) {
11321129
}
11331130
}
11341131

1132+
void MetaspaceShared::report_loading_error(const char* format, ...) {
1133+
// If the user doesn't specify any CDS options, we will try to load the default CDS archive, which
1134+
// may fail due to incompatible VM options. Print at the info level to avoid excessive verbosity.
1135+
// However, if the user has specified a CDS archive (or AOT cache), they would be interested in
1136+
// knowing that the loading fails, so we print at the error level.
1137+
Log(cds) log;
1138+
LogStream ls_error(log.error());
1139+
LogStream ls_info(log.info());
1140+
LogStream& ls = (!CDSConfig::is_using_archive()) || CDSConfig::is_using_only_default_archive() ? ls_info : ls_error;
1141+
1142+
static bool printed_error = false;
1143+
if (!printed_error) { // No need for locks. Loading error checks happen only in main thread.
1144+
ls.print_cr("An error has occurred while processing the %s. Run with -Xlog:cds for details.", CDSConfig::type_of_archive_being_loaded());
1145+
printed_error = true;
1146+
}
1147+
1148+
if (format != nullptr) {
1149+
va_list ap;
1150+
va_start(ap, format);
1151+
ls.vprint_cr(format, ap);
1152+
va_end(ap);
1153+
}
1154+
}
1155+
11351156
// This function is called when the JVM is unable to write the specified CDS archive due to an
11361157
// unrecoverable error.
11371158
void MetaspaceShared::unrecoverable_writing_error(const char* message) {
@@ -1193,11 +1214,14 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() {
11931214
// The base archive cannot be mapped. We cannot dump the dynamic shared archive.
11941215
AutoCreateSharedArchive = false;
11951216
CDSConfig::disable_dumping_dynamic_archive();
1196-
log_info(cds)("Unable to map shared spaces");
11971217
if (PrintSharedArchiveAndExit) {
11981218
MetaspaceShared::unrecoverable_loading_error("Unable to use shared archive.");
1199-
} else if (RequireSharedSpaces) {
1200-
MetaspaceShared::unrecoverable_loading_error("Unable to map shared spaces");
1219+
} else {
1220+
if (RequireSharedSpaces) {
1221+
MetaspaceShared::unrecoverable_loading_error("Unable to map shared spaces");
1222+
} else {
1223+
report_loading_error("Unable to map shared spaces");
1224+
}
12011225
}
12021226
}
12031227

@@ -1712,8 +1736,8 @@ MapArchiveResult MetaspaceShared::map_archive(FileMapInfo* mapinfo, char* mapped
17121736

17131737
mapinfo->set_is_mapped(false);
17141738
if (mapinfo->core_region_alignment() != (size_t)core_region_alignment()) {
1715-
log_info(cds)("Unable to map CDS archive -- core_region_alignment() expected: %zu"
1716-
" actual: %zu", mapinfo->core_region_alignment(), core_region_alignment());
1739+
report_loading_error("Unable to map CDS archive -- core_region_alignment() expected: %zu"
1740+
" actual: %zu", mapinfo->core_region_alignment(), core_region_alignment());
17171741
return MAP_ARCHIVE_OTHER_FAILURE;
17181742
}
17191743

src/hotspot/share/cds/metaspaceShared.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ class MetaspaceShared : AllStatic {
110110
static bool is_shared_dynamic(void* p) NOT_CDS_RETURN_(false);
111111
static bool is_shared_static(void* p) NOT_CDS_RETURN_(false);
112112

113-
static void unrecoverable_loading_error(const char* message = nullptr);
113+
static void unrecoverable_loading_error(const char* message = nullptr) ATTRIBUTE_PRINTF(1, 0);
114+
static void report_loading_error(const char* format, ...) ATTRIBUTE_PRINTF(1, 0);
114115
static void unrecoverable_writing_error(const char* message = nullptr);
115116
static void writing_error(const char* message = nullptr);
116117

src/hotspot/share/classfile/modules.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -604,21 +604,21 @@ void Modules::ArchivedProperty::runtime_check() const {
604604
bool disable = false;
605605
if (runtime_value == nullptr) {
606606
if (_archived_value != nullptr) {
607-
log_info(cds)("Mismatched values for property %s: %s specified during dump time but not during runtime", _prop, _archived_value);
607+
MetaspaceShared::report_loading_error("Mismatched values for property %s: %s specified during dump time but not during runtime", _prop, _archived_value);
608608
disable = true;
609609
}
610610
} else {
611611
if (_archived_value == nullptr) {
612-
log_info(cds)("Mismatched values for property %s: %s specified during runtime but not during dump time", _prop, runtime_value);
612+
MetaspaceShared::report_loading_error("Mismatched values for property %s: %s specified during runtime but not during dump time", _prop, runtime_value);
613613
disable = true;
614614
} else if (strcmp(runtime_value, _archived_value) != 0) {
615-
log_info(cds)("Mismatched values for property %s: runtime %s dump time %s", _prop, runtime_value, _archived_value);
615+
MetaspaceShared::report_loading_error("Mismatched values for property %s: runtime %s dump time %s", _prop, runtime_value, _archived_value);
616616
disable = true;
617617
}
618618
}
619619

620620
if (disable) {
621-
log_info(cds)("Disabling optimized module handling");
621+
MetaspaceShared::report_loading_error("Disabling optimized module handling");
622622
CDSConfig::stop_using_optimized_module_handling();
623623
}
624624
}

test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public class SharedArchiveConsistency {
5454
};
5555

5656
public static final String HELLO_WORLD = "Hello World";
57+
public static final String errMsg = "An error has occurred while processing the shared archive file.";
5758

5859
public static int num_regions = shared_region_name.length;
5960
public static String[] matchMessages = {
@@ -170,6 +171,7 @@ public static void main(String... args) throws Exception {
170171
output = shareAuto ? TestCommon.execAuto(execArgs) : TestCommon.execCommon(execArgs);
171172
output.shouldContain("The shared archive file was created by a different version or build of HotSpot");
172173
output.shouldNotContain("Checksum verification failed");
174+
output.shouldContain(errMsg);
173175
if (shareAuto) {
174176
output.shouldContain(HELLO_WORLD);
175177
}
@@ -194,6 +196,7 @@ public static void main(String... args) throws Exception {
194196
CDSArchiveUtils.modifyHeaderIntField(copiedJsa, CDSArchiveUtils.offsetVersion(), version);
195197
output = shareAuto ? TestCommon.execAuto(execArgs) : TestCommon.execCommon(execArgs);
196198
output.shouldContain("The shared archive file version " + hex(version) + " does not match the required version " + hex(currentCDSArchiveVersion));
199+
output.shouldContain(errMsg);
197200
if (shareAuto) {
198201
output.shouldContain(HELLO_WORLD);
199202
}
@@ -237,26 +240,26 @@ public static void main(String... args) throws Exception {
237240
System.out.println("\n5. Insert bytes at beginning of data section, should fail\n");
238241
String insertBytes = startNewArchive("insert-bytes");
239242
CDSArchiveUtils.insertBytesRandomlyAfterHeader(orgJsaFile, insertBytes);
240-
testAndCheck(verifyExecArgs);
243+
testAndCheck(verifyExecArgs, errMsg);
241244

242245
// delete bytes in data section forward
243246
System.out.println("\n6a. Delete bytes at beginning of data section, should fail\n");
244247
String deleteBytes = startNewArchive("delete-bytes");
245248
CDSArchiveUtils.deleteBytesAtRandomPositionAfterHeader(orgJsaFile, deleteBytes, 4096 /*bytes*/);
246-
testAndCheck(verifyExecArgs);
249+
testAndCheck(verifyExecArgs, errMsg);
247250

248251
// delete bytes at the end
249252
System.out.println("\n6b. Delete bytes at the end, should fail\n");
250253
deleteBytes = startNewArchive("delete-bytes-end");
251254
CDSArchiveUtils.deleteBytesAtTheEnd(orgJsaFile, deleteBytes);
252-
testAndCheck(verifyExecArgs, "The shared archive file has been truncated.");
255+
testAndCheck(verifyExecArgs, "The shared archive file has been truncated.", errMsg);
253256

254257
// modify contents in random area
255258
System.out.println("\n7. modify Content in random areas, should fail\n");
256259
String randomAreas = startNewArchive("random-areas");
257260
copiedJsa = CDSArchiveUtils.copyArchiveFile(orgJsaFile, randomAreas);
258261
CDSArchiveUtils.modifyRegionContentRandomly(copiedJsa);
259-
testAndCheck(verifyExecArgs);
262+
testAndCheck(verifyExecArgs, errMsg);
260263

261264
// modify _base_archive_name_offet to non-zero
262265
System.out.println("\n8. modify _base_archive_name_offset to non-zero\n");

0 commit comments

Comments
 (0)