Skip to content

Commit e3ece36

Browse files
author
Matias Saavedra Silva
committed
8303422: Use common functions to exit the VM for -Xshare:dump and CDS errors
Reviewed-by: iklam, coleenp, fparain
1 parent bb1a7bb commit e3ece36

9 files changed

+82
-66
lines changed

src/hotspot/share/cds/archiveBuilder.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ address ArchiveBuilder::reserve_buffer() {
331331
ReservedSpace rs(buffer_size, MetaspaceShared::core_region_alignment(), os::vm_page_size());
332332
if (!rs.is_reserved()) {
333333
log_error(cds)("Failed to reserve " SIZE_FORMAT " bytes of output buffer.", buffer_size);
334-
os::_exit(0);
334+
MetaspaceShared::unrecoverable_writing_error();
335335
}
336336

337337
// buffer_bottom is the lowest address of the 2 core regions (rw, ro) when
@@ -381,7 +381,7 @@ address ArchiveBuilder::reserve_buffer() {
381381
log_error(cds)("my_archive_requested_top = " INTPTR_FORMAT, p2i(my_archive_requested_top));
382382
log_error(cds)("SharedBaseAddress (" INTPTR_FORMAT ") is too high. "
383383
"Please rerun java -Xshare:dump with a lower value", p2i(_requested_static_archive_bottom));
384-
os::_exit(0);
384+
MetaspaceShared::unrecoverable_writing_error();
385385
}
386386

387387
if (DumpSharedSpaces) {
@@ -1269,8 +1269,8 @@ void ArchiveBuilder::report_out_of_space(const char* name, size_t needed_bytes)
12691269
_rw_region.print_out_of_space_msg(name, needed_bytes);
12701270
_ro_region.print_out_of_space_msg(name, needed_bytes);
12711271

1272-
vm_exit_during_initialization(err_msg("Unable to allocate from '%s' region", name),
1273-
"Please reduce the number of shared classes.");
1272+
log_error(cds)("Unable to allocate from '%s' region: Please reduce the number of shared classes.", name);
1273+
MetaspaceShared::unrecoverable_writing_error();
12741274
}
12751275

12761276

src/hotspot/share/cds/archiveUtils.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ char* DumpRegion::expand_top_to(char* newtop) {
164164
// This is just a sanity check and should not appear in any real world usage. This
165165
// happens only if you allocate more than 2GB of shared objects and would require
166166
// millions of shared classes.
167-
vm_exit_during_initialization("Out of memory in the CDS archive",
168-
"Please reduce the number of shared classes.");
167+
log_error(cds)("Out of memory in the CDS archive: Please reduce the number of shared classes.");
168+
MetaspaceShared::unrecoverable_writing_error();
169169
}
170170
}
171171

@@ -190,8 +190,9 @@ void DumpRegion::commit_to(char* newtop) {
190190
assert(commit <= uncommitted, "sanity");
191191

192192
if (!_vs->expand_by(commit, false)) {
193-
vm_exit_during_initialization(err_msg("Failed to expand shared space to " SIZE_FORMAT " bytes",
194-
need_committed_size));
193+
log_error(cds)("Failed to expand shared space to " SIZE_FORMAT " bytes",
194+
need_committed_size);
195+
MetaspaceShared::unrecoverable_writing_error();
195196
}
196197

197198
const char* which;

src/hotspot/share/cds/dynamicArchive.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,8 @@ void DynamicArchive::check_for_dynamic_dump() {
367367

368368
#define __THEMSG " is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info."
369369
if (RecordDynamicDumpInfo) {
370-
vm_exit_during_initialization("-XX:+RecordDynamicDumpInfo" __THEMSG, nullptr);
370+
log_error(cds)("-XX:+RecordDynamicDumpInfo%s", __THEMSG);
371+
MetaspaceShared::unrecoverable_loading_error();
371372
} else {
372373
assert(ArchiveClassesAtExit != nullptr, "sanity");
373374
log_warning(cds)("-XX:ArchiveClassesAtExit" __THEMSG);

src/hotspot/share/cds/filemap.cpp

Lines changed: 18 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -80,29 +80,6 @@
8080
#define O_BINARY 0 // otherwise do nothing.
8181
#endif
8282

83-
// Complain and stop. All error conditions occurring during the writing of
84-
// an archive file should stop the process. Unrecoverable errors during
85-
// the reading of the archive file should stop the process.
86-
87-
static void fail_exit(const char *msg, va_list ap) {
88-
// This occurs very early during initialization: tty is not initialized.
89-
jio_fprintf(defaultStream::error_stream(),
90-
"An error has occurred while processing the"
91-
" shared archive file.\n");
92-
jio_vfprintf(defaultStream::error_stream(), msg, ap);
93-
jio_fprintf(defaultStream::error_stream(), "\n");
94-
// Do not change the text of the below message because some tests check for it.
95-
vm_exit_during_initialization("Unable to use shared archive.", nullptr);
96-
}
97-
98-
99-
void FileMapInfo::fail_stop(const char *msg, ...) {
100-
va_list ap;
101-
va_start(ap, msg);
102-
fail_exit(msg, ap); // Never returns.
103-
va_end(ap); // for completeness.
104-
}
105-
10683
// Fill in the fileMapInfo structure with data about this VM instance.
10784

10885
// This method copies the vm version info into header_version. If the version is too
@@ -367,7 +344,8 @@ void SharedClassPathEntry::init(bool is_modules_image,
367344
//
368345
// If we can't access a jar file in the boot path, then we can't
369346
// make assumptions about where classes get loaded from.
370-
FileMapInfo::fail_stop("Unable to open file %s.", cpe->name());
347+
log_error(cds)("Unable to open file %s.", cpe->name());
348+
MetaspaceShared::unrecoverable_loading_error();
371349
}
372350

373351
// No need to save the name of the module file, as it will be computed at run time
@@ -1097,7 +1075,8 @@ bool FileMapInfo::validate_shared_path_table() {
10971075
const char* hint_msg = log_is_enabled(Info, class, path) ?
10981076
"" : " (hint: enable -Xlog:class+path=info to diagnose the failure)";
10991077
if (RequireSharedSpaces) {
1100-
fail_stop("%s%s", mismatch_msg, hint_msg);
1078+
log_error(cds)("%s%s", mismatch_msg, hint_msg);
1079+
MetaspaceShared::unrecoverable_loading_error();
11011080
} else {
11021081
log_warning(cds)("%s%s", mismatch_msg, hint_msg);
11031082
}
@@ -1447,7 +1426,8 @@ bool FileMapInfo::init_from_file(int fd) {
14471426

14481427
void FileMapInfo::seek_to_position(size_t pos) {
14491428
if (os::lseek(_fd, (long)pos, SEEK_SET) < 0) {
1450-
fail_stop("Unable to seek to position " SIZE_FORMAT, pos);
1429+
log_error(cds)("Unable to seek to position %ld", pos);
1430+
MetaspaceShared::unrecoverable_loading_error();
14511431
}
14521432
}
14531433

@@ -1493,8 +1473,9 @@ void FileMapInfo::open_for_write() {
14931473
remove(_full_path);
14941474
int fd = os::open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444);
14951475
if (fd < 0) {
1496-
fail_stop("Unable to create shared archive file %s: (%s).", _full_path,
1497-
os::strerror(errno));
1476+
log_error(cds)("Unable to create shared archive file %s: (%s).", _full_path,
1477+
os::strerror(errno));
1478+
MetaspaceShared::unrecoverable_writing_error();
14981479
}
14991480
_fd = fd;
15001481
_file_open = true;
@@ -1731,11 +1712,12 @@ size_t FileMapInfo::write_heap_regions(GrowableArray<MemRegion>* regions,
17311712

17321713
int arr_len = regions == nullptr ? 0 : regions->length();
17331714
if (arr_len > max_num_regions) {
1734-
fail_stop("Unable to write archive heap memory regions: "
1735-
"number of memory regions exceeds maximum due to fragmentation. "
1736-
"Please increase java heap size "
1737-
"(current MaxHeapSize is " SIZE_FORMAT ", InitialHeapSize is " SIZE_FORMAT ").",
1738-
MaxHeapSize, InitialHeapSize);
1715+
log_error(cds)("Unable to write archive heap memory regions: "
1716+
"number of memory regions exceeds maximum due to fragmentation. "
1717+
"Please increase java heap size "
1718+
"(current MaxHeapSize is " SIZE_FORMAT ", InitialHeapSize is " SIZE_FORMAT ").",
1719+
MaxHeapSize, InitialHeapSize);
1720+
MetaspaceShared::unrecoverable_writing_error();
17391721
}
17401722

17411723
size_t total_size = 0;
@@ -1769,7 +1751,7 @@ void FileMapInfo::write_bytes(const void* buffer, size_t nbytes) {
17691751
// If the shared archive is corrupted, close it and remove it.
17701752
close();
17711753
remove(_full_path);
1772-
fail_stop("Unable to write to shared archive file.");
1754+
MetaspaceShared::unrecoverable_writing_error("Unable to write to shared archive file.");
17731755
}
17741756
_file_offset += nbytes;
17751757
}
@@ -1810,7 +1792,7 @@ void FileMapInfo::write_bytes_aligned(const void* buffer, size_t nbytes) {
18101792
void FileMapInfo::close() {
18111793
if (_file_open) {
18121794
if (::close(_fd) < 0) {
1813-
fail_stop("Unable to close the shared archive file.");
1795+
MetaspaceShared::unrecoverable_loading_error("Unable to close the shared archive file.");
18141796
}
18151797
_file_open = false;
18161798
_fd = -1;
@@ -2537,7 +2519,7 @@ void FileMapInfo::unmap_region(int i) {
25372519

25382520
void FileMapInfo::assert_mark(bool check) {
25392521
if (!check) {
2540-
fail_stop("Mark mismatch while restoring from shared file.");
2522+
MetaspaceShared::unrecoverable_loading_error("Mark mismatch while restoring from shared file.");
25412523
}
25422524
}
25432525

src/hotspot/share/cds/filemap.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,8 +482,6 @@ class FileMapInfo : public CHeapObj<mtInternal> {
482482
// Remap the shared readonly space to shared readwrite, private.
483483
bool remap_shared_readonly_as_readwrite();
484484

485-
// Errors.
486-
static void fail_stop(const char *msg, ...) ATTRIBUTE_PRINTF(1, 2);
487485
static bool memory_mapping_failed() {
488486
CDS_ONLY(return _memory_mapping_failed;)
489487
NOT_CDS(return false;)

src/hotspot/share/cds/heapShared.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ void KlassSubGraphInfo::check_allowed_klass(InstanceKlass* ik) {
735735
ResourceMark rm;
736736
log_error(cds, heap)("Class %s not allowed in archive heap. Must be in java.base%s",
737737
ik->external_name(), extra_msg);
738-
os::_exit(1);
738+
MetaspaceShared::unrecoverable_writing_error();
739739
}
740740

741741
bool KlassSubGraphInfo::is_non_early_klass(Klass* k) {
@@ -1213,7 +1213,7 @@ bool HeapShared::archive_reachable_objects_from(int level,
12131213
// these objects that are referenced (directly or indirectly) by static fields.
12141214
ResourceMark rm;
12151215
log_error(cds, heap)("Cannot archive object of class %s", orig_obj->klass()->external_name());
1216-
os::_exit(1);
1216+
MetaspaceShared::unrecoverable_writing_error();
12171217
}
12181218

12191219
// java.lang.Class instances cannot be included in an archived object sub-graph. We only support
@@ -1223,7 +1223,7 @@ bool HeapShared::archive_reachable_objects_from(int level,
12231223
// object that is referenced (directly or indirectly) by static fields.
12241224
if (java_lang_Class::is_instance(orig_obj) && subgraph_info != _default_subgraph_info) {
12251225
log_error(cds, heap)("(%d) Unknown java.lang.Class object is in the archived sub-graph", level);
1226-
os::_exit(1);
1226+
MetaspaceShared::unrecoverable_writing_error();
12271227
}
12281228

12291229
if (has_been_seen_during_subgraph_recording(orig_obj)) {
@@ -1252,7 +1252,7 @@ bool HeapShared::archive_reachable_objects_from(int level,
12521252
// We don't know how to handle an object that has been archived, but some of its reachable
12531253
// objects cannot be archived. Bail out for now. We might need to fix this in the future if
12541254
// we have a real use case.
1255-
os::_exit(1);
1255+
MetaspaceShared::unrecoverable_writing_error();
12561256
}
12571257
}
12581258
}

src/hotspot/share/cds/metaspaceShared.cpp

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,8 @@ void MetaspaceShared::initialize_for_static_dump() {
267267
size_t symbol_rs_size = LP64_ONLY(3 * G) NOT_LP64(128 * M);
268268
_symbol_rs = ReservedSpace(symbol_rs_size);
269269
if (!_symbol_rs.is_reserved()) {
270-
vm_exit_during_initialization("Unable to reserve memory for symbols",
271-
err_msg(SIZE_FORMAT " bytes.", symbol_rs_size));
270+
log_error(cds)("Unable to reserve memory for symbols: %ld bytes.", symbol_rs_size);
271+
MetaspaceShared::unrecoverable_writing_error();
272272
}
273273
_symbol_region.init(&_symbol_rs, &_symbol_vs);
274274
}
@@ -309,7 +309,8 @@ void MetaspaceShared::read_extra_data(JavaThread* current, const char* filename)
309309
ResourceMark rm(current);
310310
if (utf8_length == 0x7fffffff) {
311311
// buf_len will overflown 32-bit value.
312-
vm_exit_during_initialization(err_msg("string length too large: %d", utf8_length));
312+
log_error(cds)("string length too large: %d", utf8_length);
313+
MetaspaceShared::unrecoverable_loading_error();
313314
}
314315
int buf_len = utf8_length+1;
315316
char* utf8_buffer = NEW_RESOURCE_ARRAY(char, buf_len);
@@ -564,10 +565,7 @@ void VM_PopulateDumpSharedSpace::doit() {
564565
"for testing purposes only and should not be used in a production environment");
565566
}
566567

567-
// There may be pending VM operations. We have changed some global states
568-
// (such as vmClasses::_klasses) that may cause these VM operations
569-
// to fail. For safety, forget these operations and exit the VM directly.
570-
os::_exit(0);
568+
MetaspaceShared::exit_after_static_dump();
571569
}
572570

573571
class CollectCLDClosure : public CLDClosure {
@@ -677,12 +675,13 @@ void MetaspaceShared::preload_and_dump() {
677675
preload_and_dump_impl(THREAD);
678676
if (HAS_PENDING_EXCEPTION) {
679677
if (PENDING_EXCEPTION->is_a(vmClasses::OutOfMemoryError_klass())) {
680-
vm_direct_exit(-1, err_msg("Out of memory. Please run with a larger Java heap, current MaxHeapSize = "
681-
SIZE_FORMAT "M", MaxHeapSize/M));
678+
log_error(cds)("Out of memory. Please run with a larger Java heap, current MaxHeapSize = "
679+
SIZE_FORMAT "M", MaxHeapSize/M);
680+
MetaspaceShared::unrecoverable_writing_error();
682681
} else {
683682
log_error(cds)("%s: %s", PENDING_EXCEPTION->klass()->external_name(),
684683
java_lang_String::as_utf8_string(java_lang_Throwable::message(PENDING_EXCEPTION)));
685-
vm_direct_exit(-1, "VM exits due to exception, use -Xlog:cds,exceptions=trace for detail");
684+
MetaspaceShared::unrecoverable_writing_error("VM exits due to exception, use -Xlog:cds,exceptions=trace for detail");
686685
}
687686
} else {
688687
// On success, the VM_PopulateDumpSharedSpace op should have
@@ -902,6 +901,37 @@ bool MetaspaceShared::is_shared_dynamic(void* p) {
902901
}
903902
}
904903

904+
// This function is called when the JVM is unable to load the specified archive(s) due to one
905+
// of the following conditions.
906+
// - There's an error that indicates that the archive(s) files were corrupt or otherwise damaged.
907+
// - When -XX:+RequireSharedSpaces is specified, AND the JVM cannot load the archive(s) due
908+
// to version or classpath mismatch.
909+
void MetaspaceShared::unrecoverable_loading_error(const char* message) {
910+
log_error(cds)("An error has occurred while processing the shared archive file.");
911+
if (message != nullptr) {
912+
log_error(cds)("%s", message);
913+
}
914+
vm_exit_during_initialization("Unable to use shared archive.", nullptr);
915+
}
916+
917+
// This function is called when the JVM is unable to write the specified CDS archive due to an
918+
// unrecoverable error.
919+
void MetaspaceShared::unrecoverable_writing_error(const char* message) {
920+
log_error(cds)("An error has occurred while writing the shared archive file.");
921+
if (message != nullptr) {
922+
log_error(cds)("%s", message);
923+
}
924+
vm_exit(1);
925+
}
926+
927+
// We have finished dumping the static archive. At this point, there may be pending VM
928+
// operations. We have changed some global states (such as vmClasses::_klasses) that
929+
// may cause these VM operations to fail. For safety, forget these operations and
930+
// exit the VM directly.
931+
void MetaspaceShared::exit_after_static_dump() {
932+
os::_exit(0);
933+
}
934+
905935
void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() {
906936
assert(UseSharedSpaces, "Must be called when UseSharedSpaces is enabled");
907937
MapArchiveResult result = MAP_ARCHIVE_OTHER_FAILURE;
@@ -950,9 +980,9 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() {
950980
DynamicDumpSharedSpaces = false;
951981
log_info(cds)("Unable to map shared spaces");
952982
if (PrintSharedArchiveAndExit) {
953-
vm_exit_during_initialization("Unable to use shared archive.");
983+
MetaspaceShared::unrecoverable_loading_error("Unable to use shared archive.");
954984
} else if (RequireSharedSpaces) {
955-
FileMapInfo::fail_stop("Unable to map shared spaces");
985+
MetaspaceShared::unrecoverable_loading_error("Unable to map shared spaces");
956986
}
957987
}
958988

@@ -967,7 +997,7 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() {
967997
delete dynamic_mapinfo;
968998
}
969999
if (RequireSharedSpaces && has_failed) {
970-
FileMapInfo::fail_stop("Unable to map shared spaces");
1000+
MetaspaceShared::unrecoverable_loading_error("Unable to map shared spaces");
9711001
}
9721002
}
9731003

@@ -995,7 +1025,7 @@ FileMapInfo* MetaspaceShared::open_dynamic_archive() {
9951025
if (!mapinfo->initialize()) {
9961026
delete(mapinfo);
9971027
if (RequireSharedSpaces) {
998-
FileMapInfo::fail_stop("Failed to initialize dynamic archive");
1028+
MetaspaceShared::unrecoverable_loading_error("Failed to initialize dynamic archive");
9991029
}
10001030
return nullptr;
10011031
}

src/hotspot/share/cds/metaspaceShared.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ class MetaspaceShared : AllStatic {
116116

117117
static bool is_shared_dynamic(void* p) NOT_CDS_RETURN_(false);
118118

119+
static void unrecoverable_loading_error(const char* message = nullptr);
120+
static void unrecoverable_writing_error(const char* message = nullptr);
121+
static void exit_after_static_dump();
122+
119123
static void serialize(SerializeClosure* sc) NOT_CDS_RETURN;
120124

121125
// JVM/TI RedefineClasses() support:

src/hotspot/share/classfile/stringTable.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ void StringTable::allocate_shared_strings_array(TRAPS) {
797797
// refer to more than 16384 * 16384 = 26M interned strings! Not a practical concern
798798
// but bail out for safety.
799799
log_error(cds)("Too many strings to be archived: " SIZE_FORMAT, _items_count);
800-
os::_exit(1);
800+
MetaspaceShared::unrecoverable_writing_error();
801801
}
802802

803803
objArrayOop primary = oopFactory::new_objArray(vmClasses::Object_klass(), primary_array_length, CHECK);

0 commit comments

Comments
 (0)