--- old/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp 2020-01-28 21:42:21.032334500 +0900 +++ new/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp 2020-01-28 21:42:20.734410800 +0900 @@ -45,6 +45,7 @@ static const char vm_soe_filename_fmt[] = "hs_soe_pid%p.jfr"; static const char chunk_file_jfr_ext[] = ".jfr"; static const size_t iso8601_len = 19; // "YYYY-MM-DDTHH:MM:SS" +static fio_fd emergency_fd = invalid_fd; static fio_fd open_exclusivly(const char* path) { return os::open(path, O_CREAT | O_RDWR, S_IREAD | S_IWRITE); @@ -212,7 +213,7 @@ return _iterator >= _files->length() ? NULL : fully_qualified(_files->at(_iterator++)); } -static void write_emergency_file(fio_fd emergency_fd, const RepositoryIterator& iterator) { +static void write_emergency_file(const RepositoryIterator& iterator) { assert(emergency_fd != invalid_fd, "invariant"); const size_t size_of_file_copy_block = 1 * M; // 1 mb jbyte* const file_copy_block = NEW_RESOURCE_ARRAY_RETURN_NULL(jbyte, size_of_file_copy_block); @@ -247,14 +248,13 @@ } } -static const char* create_emergency_dump_path() { - char* buffer = NEW_RESOURCE_ARRAY_RETURN_NULL(char, JVM_MAXPATHLEN); - if (NULL == buffer) { - return NULL; - } +// "emergency_dump_path" have to be allocated JVM_MAXPATHLEN or larger. +static void create_emergency_dump_path(char* emergency_dump_path) { + char buffer[JVM_MAXPATHLEN]; + emergency_dump_path[0] = '\0'; const char* const cwd = os::get_current_directory(buffer, JVM_MAXPATHLEN); if (NULL == cwd) { - return NULL; + return; } size_t pos = strlen(cwd); const int fsep_len = jio_snprintf(&buffer[pos], JVM_MAXPATHLEN - pos, "%s", os::file_separator()); @@ -270,21 +270,14 @@ default: filename_fmt = vm_error_filename_fmt; } - char* emergency_dump_path = NULL; pos += fsep_len; if (Arguments::copy_expand_pid(filename_fmt, strlen(filename_fmt), &buffer[pos], JVM_MAXPATHLEN - pos)) { - const size_t emergency_filename_length = strlen(buffer); - emergency_dump_path = NEW_RESOURCE_ARRAY_RETURN_NULL(char, emergency_filename_length + 1); - if (NULL == emergency_dump_path) { - return NULL; - } - strncpy(emergency_dump_path, buffer, emergency_filename_length + 1); + strncpy(emergency_dump_path, buffer, JVM_MAXPATHLEN); } - if (emergency_dump_path != NULL) { + if (emergency_dump_path[0] != '\0') { log_info(jfr)( // For user, should not be "jfr, system" "Attempting to recover JFR data, emergency jfr file: %s", emergency_dump_path); } - return emergency_dump_path; } // Caller needs ResourceMark @@ -309,24 +302,35 @@ return chunk_path; } -static fio_fd emergency_dump_file_descriptor() { - ResourceMark rm; - const char* const emergency_dump_path = create_emergency_dump_path(); - return emergency_dump_path != NULL ? open_exclusivly(emergency_dump_path) : invalid_fd; +void JfrEmergencyDump::setup_emergency_dump_file_descriptor() { + assert(emergency_fd == invalid_fd, "invariant"); + char emergency_dump_path[JVM_MAXPATHLEN]; + create_emergency_dump_path(emergency_dump_path); + emergency_fd = (emergency_dump_path[0] != '\0') ? open_exclusivly(emergency_dump_path) : invalid_fd; } +// Caller needs ResourceMark const char* JfrEmergencyDump::build_dump_path(const char* repository_path) { - return repository_path == NULL ? create_emergency_dump_path() : create_emergency_chunk_path(repository_path); + if (repository_path == NULL) { + char* dump_path = NEW_RESOURCE_ARRAY_RETURN_NULL(char, JVM_MAXPATHLEN); + if (dump_path == NULL) { + return NULL; + } + create_emergency_dump_path(dump_path); + return dump_path; + } else { + return create_emergency_chunk_path(repository_path); + } } void JfrEmergencyDump::on_vm_error(const char* repository_path) { assert(repository_path != NULL, "invariant"); ResourceMark rm; - const fio_fd emergency_fd = emergency_dump_file_descriptor(); if (emergency_fd != invalid_fd) { RepositoryIterator iterator(repository_path, strlen(repository_path)); - write_emergency_file(emergency_fd, iterator); + write_emergency_file(iterator); os::close(emergency_fd); + emergency_fd = invalid_fd; } }