--- old/src/hotspot/share/jfr/jfr.cpp 2020-01-22 14:38:27.391876400 +0900 +++ new/src/hotspot/share/jfr/jfr.cpp 2020-01-22 14:38:27.092969500 +0900 @@ -29,6 +29,7 @@ #include "jfr/recorder/jfrRecorder.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" #include "jfr/recorder/repository/jfrEmergencyDump.hpp" +#include "jfr/recorder/repository/jfrRepository.hpp" #include "jfr/recorder/service/jfrOptionSet.hpp" #include "jfr/support/jfrThreadLocal.hpp" #include "runtime/java.hpp" @@ -114,3 +115,11 @@ bool Jfr::on_start_flight_recording_option(const JavaVMOption** option, char* delimiter) { return JfrOptionSet::parse_start_flight_recording_option(option, delimiter); } + +const char* Jfr::get_emergency_dump_path() { + return JfrEmergencyDump::dump_path(); +} + +const char* Jfr::get_repository_path() { + return JfrRepository::get_path(); +} --- old/src/hotspot/share/jfr/jfr.hpp 2020-01-22 14:38:28.514868100 +0900 +++ new/src/hotspot/share/jfr/jfr.hpp 2020-01-22 14:38:28.234795500 +0900 @@ -57,6 +57,8 @@ static void exclude_thread(Thread* thread); static bool is_excluded(Thread* thread); static void include_thread(Thread* thread); + static const char* get_emergency_dump_path(); + static const char* get_repository_path(); }; #endif // SHARE_JFR_JFR_HPP --- old/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp 2020-01-22 14:38:29.521242600 +0900 +++ new/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp 2020-01-22 14:38:29.261460800 +0900 @@ -46,6 +46,8 @@ static const char chunk_file_jfr_ext[] = ".jfr"; static const size_t iso8601_len = 19; // "YYYY-MM-DDTHH:MM:SS" +char JfrEmergencyDump::_dump_path[JVM_MAXPATHLEN] = {0}; + static fio_fd open_exclusivly(const char* path) { return os::open(path, O_CREAT | O_RDWR, S_IREAD | S_IWRITE); } @@ -247,17 +249,17 @@ } } -static const char* create_emergency_dump_path() { - char* buffer = NEW_RESOURCE_ARRAY_RETURN_NULL(char, JVM_MAXPATHLEN); - if (NULL == buffer) { - return NULL; +const char* JfrEmergencyDump::create_emergency_dump_path() { + if (*_dump_path != '\0') { + return _dump_path; } - const char* const cwd = os::get_current_directory(buffer, JVM_MAXPATHLEN); + + const char* const cwd = os::get_current_directory(_dump_path, JVM_MAXPATHLEN); if (NULL == cwd) { return NULL; } size_t pos = strlen(cwd); - const int fsep_len = jio_snprintf(&buffer[pos], JVM_MAXPATHLEN - pos, "%s", os::file_separator()); + const int fsep_len = jio_snprintf(&_dump_path[pos], JVM_MAXPATHLEN - pos, "%s", os::file_separator()); const char* filename_fmt = NULL; // fetch specific error cause switch (JfrJavaSupport::cause()) { @@ -270,26 +272,23 @@ 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); - } - if (emergency_dump_path != NULL) { + Arguments::copy_expand_pid(filename_fmt, strlen(filename_fmt), &_dump_path[pos], JVM_MAXPATHLEN - pos); + if (*_dump_path != '\0') { log_info(jfr)( // For user, should not be "jfr, system" - "Attempting to recover JFR data, emergency jfr file: %s", emergency_dump_path); + "Attempting to recover JFR data, emergency jfr file: %s", _dump_path); } - return emergency_dump_path; + return _dump_path; } // Caller needs ResourceMark -static const char* create_emergency_chunk_path(const char* repository_path) { +const char* JfrEmergencyDump::create_emergency_chunk_path(const char* repository_path) { assert(repository_path != NULL, "invariant"); + + if (*_dump_path != '\0') { + return _dump_path; + } + const size_t repository_path_len = strlen(repository_path); // date time char date_time_buffer[32] = { 0 }; @@ -300,16 +299,12 @@ + date_time_len // date_time + strlen(chunk_file_jfr_ext) // .jfr + 1; - char* chunk_path = NEW_RESOURCE_ARRAY_RETURN_NULL(char, chunkname_max_len); - if (chunk_path == NULL) { - return NULL; - } // append the individual substrings - jio_snprintf(chunk_path, chunkname_max_len, "%s%s%s%s", repository_path, os::file_separator(), date_time_buffer, chunk_file_jfr_ext); - return chunk_path; + jio_snprintf(_dump_path, chunkname_max_len, "%s%s%s%s", repository_path, os::file_separator(), date_time_buffer, chunk_file_jfr_ext); + return _dump_path; } -static fio_fd emergency_dump_file_descriptor() { +fio_fd JfrEmergencyDump::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; --- old/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.hpp 2020-01-22 14:38:30.559358300 +0900 +++ new/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.hpp 2020-01-22 14:38:30.296082100 +0900 @@ -26,15 +26,22 @@ #define SHARE_JFR_RECORDER_REPOSITORY_JFREMERGENCYDUMP_HPP #include "memory/allocation.hpp" +#include "jfr/utilities/jfrTypes.hpp" // // Responsible for creating an hs_err.jfr file in exceptional shutdown situations (crash, OOM) // class JfrEmergencyDump : AllStatic { + private: + static char _dump_path[]; + static const char* create_emergency_dump_path(); + static const char* create_emergency_chunk_path(const char* repository_path); + static fio_fd emergency_dump_file_descriptor(); public: static void on_vm_shutdown(bool exception_handler); static void on_vm_error(const char* repository_path); static const char* build_dump_path(const char* repository_path); + static const char* dump_path() { return _dump_path; } }; #endif // SHARE_JFR_RECORDER_REPOSITORY_JFREMERGENCYDUMP_HPP --- old/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp 2020-01-22 14:38:31.570693700 +0900 +++ new/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp 2020-01-22 14:38:31.296953500 +0900 @@ -104,6 +104,10 @@ return true; } +const char* JfrRepository::get_path() { + return (_instance == NULL) ? NULL : _instance->_path; +} + void JfrRepository::notify_on_new_chunk_path() { if (Jfr::is_recording()) { // rotations are synchronous, block until rotation completes --- old/src/hotspot/share/jfr/recorder/repository/jfrRepository.hpp 2020-01-22 14:38:32.589942100 +0900 +++ new/src/hotspot/share/jfr/recorder/repository/jfrRepository.hpp 2020-01-22 14:38:32.323692600 +0900 @@ -69,6 +69,7 @@ public: static void set_path(jstring location, JavaThread* jt); + static const char* get_path(); static void set_chunk_path(jstring path, JavaThread* jt); static void mark_chunk_final(); static void flush(JavaThread* jt); --- old/src/hotspot/share/utilities/vmError.cpp 2020-01-22 14:38:33.602858900 +0900 +++ new/src/hotspot/share/utilities/vmError.cpp 2020-01-22 14:38:33.352826800 +0900 @@ -148,6 +148,30 @@ out->print_raw_cr("#"); } +#if INCLUDE_JFR +static void print_jfr_path(outputStream *out) { + if (out == NULL) { + return; + } + + const char *path = Jfr::get_emergency_dump_path(); + if (*path != '\0') { + out->print_raw_cr("# JFR data is saved as:"); + out->print_raw ("# "); + out->print_raw_cr(path); + out->print_raw_cr("#"); + } else { + path = Jfr::get_repository_path(); + if ((path != NULL) && (*path != '\0')) { + out->print_raw_cr("# JFR files might be saved in the repository:"); + out->print_raw ("# "); + out->print_raw_cr(path); + out->print_raw_cr("#"); + } + } +} +#endif + bool VMError::coredump_status; char VMError::coredump_message[O_BUFLEN]; @@ -618,6 +642,14 @@ st->cr(); st->print_cr("#"); +#if INCLUDE_JFR + STEP("printing jfr repository") + + if (_verbose) { + print_jfr_path(st); + } +#endif + STEP("printing bug submit message") if (should_report_bug(_id) && _verbose) { @@ -1536,6 +1568,7 @@ } log.set_fd(-1); + out.print_raw_cr("#"); } if (PrintNMTStatistics) { @@ -1562,15 +1595,23 @@ out.print_raw("#\n# Can't open file to dump replay data. Error: "); out.print_raw_cr(os::strerror(e)); } + out.print_raw_cr("#"); } } } +#if INCLUDE_JFR + static bool skip_jfr_repository = false; + if (!skip_jfr_repository) { + skip_jfr_repository = true; + print_jfr_path(&out); + out.print_raw_cr("#"); + } +#endif + static bool skip_bug_url = !should_report_bug(_id); if (!skip_bug_url) { skip_bug_url = true; - - out.print_raw_cr("#"); print_bug_submit_message(&out, _thread); }