--- old/src/hotspot/share/jfr/jfr.cpp 2020-02-11 22:39:40.262682600 +0900 +++ new/src/hotspot/share/jfr/jfr.cpp 2020-02-11 22:39:39.473232500 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -30,6 +30,7 @@ #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" #include "jfr/recorder/repository/jfrEmergencyDump.hpp" #include "jfr/recorder/service/jfrOptionSet.hpp" +#include "jfr/recorder/repository/jfrRepository.hpp" #include "jfr/support/jfrThreadLocal.hpp" #include "runtime/java.hpp" @@ -114,3 +115,17 @@ bool Jfr::on_start_flight_recording_option(const JavaVMOption** option, char* delimiter) { return JfrOptionSet::parse_start_flight_recording_option(option, delimiter); } + +void Jfr::setup_emergency_dump_file_descriptor() { + if (JfrRecorder::is_recording()) { + JfrEmergencyDump::setup_emergency_dump_file_descriptor(); + } +} + +const char* Jfr::saved_emergency_dump_path() { + return JfrEmergencyDump::saved_emergency_dump_path(); +} + +const char* Jfr::repository_path() { + return JfrRepository::path(); +} --- old/src/hotspot/share/jfr/jfr.hpp 2020-02-11 22:39:42.976580600 +0900 +++ new/src/hotspot/share/jfr/jfr.hpp 2020-02-11 22:39:42.183387200 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -57,6 +57,9 @@ static void exclude_thread(Thread* thread); static bool is_excluded(Thread* thread); static void include_thread(Thread* thread); + static void setup_emergency_dump_file_descriptor(); + static const char* saved_emergency_dump_path(); + static const char* repository_path(); }; #endif // SHARE_JFR_JFR_HPP --- old/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp 2020-02-11 22:39:45.689803200 +0900 +++ new/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp 2020-02-11 22:39:44.899499000 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -40,11 +40,14 @@ #include "runtime/thread.inline.hpp" #include "utilities/growableArray.hpp" +char JfrEmergencyDump::_saved_emergency_dump_path[JVM_MAXPATHLEN] = {0}; + static const char vm_error_filename_fmt[] = "hs_err_pid%p.jfr"; static const char vm_oom_filename_fmt[] = "hs_oom_pid%p.jfr"; 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 +215,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,11 +250,9 @@ } } -static const char* create_emergency_dump_path() { - char* buffer = NEW_RESOURCE_ARRAY_RETURN_NULL(char, JVM_MAXPATHLEN); - if (NULL == buffer) { - return NULL; - } +static const char* create_emergency_dump_path(char* emergency_dump_path, size_t len) { + 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; @@ -270,25 +271,22 @@ 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) { + if ((emergency_filename_length + 1) > len) { // includes NUL char return NULL; } - strncpy(emergency_dump_path, buffer, emergency_filename_length + 1); + strncpy(emergency_dump_path, buffer, len); } - 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 -static const char* create_emergency_chunk_path(const char* repository_path) { +static const char* create_emergency_chunk_path(const char* repository_path, char* chunk_path, size_t chunk_path_len) { assert(repository_path != NULL, "invariant"); const size_t repository_path_len = strlen(repository_path); // date time @@ -300,8 +298,7 @@ + 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) { + if (chunk_path_len < chunkname_max_len) { return NULL; } // append the individual substrings @@ -309,24 +306,25 @@ 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"); + create_emergency_dump_path(_saved_emergency_dump_path, JVM_MAXPATHLEN); + emergency_fd = (_saved_emergency_dump_path[0] != '\0') ? open_exclusivly(_saved_emergency_dump_path) : invalid_fd; } -const char* JfrEmergencyDump::build_dump_path(const char* repository_path) { - return repository_path == NULL ? create_emergency_dump_path() : create_emergency_chunk_path(repository_path); +const char* JfrEmergencyDump::build_dump_path(const char* repository_path, char* dump_path, size_t dump_path_len) { + return repository_path == NULL ? create_emergency_dump_path(dump_path, dump_path_len) + : create_emergency_chunk_path(repository_path, dump_path, dump_path_len); } 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; } } --- old/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.hpp 2020-02-11 22:39:48.469979000 +0900 +++ new/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.hpp 2020-02-11 22:39:47.663930700 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -31,10 +31,15 @@ // Responsible for creating an hs_err.jfr file in exceptional shutdown situations (crash, OOM) // class JfrEmergencyDump : AllStatic { + private: + static char _saved_emergency_dump_path[JVM_MAXPATHLEN]; + public: + static void setup_emergency_dump_file_descriptor(); 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* build_dump_path(const char* repository_path, char* dump_path, size_t dump_path_len); + static const char* saved_emergency_dump_path() { return _saved_emergency_dump_path; } }; #endif // SHARE_JFR_RECORDER_REPOSITORY_JFREMERGENCYDUMP_HPP --- old/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp 2020-02-11 22:39:51.288835900 +0900 +++ new/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp 2020-02-11 22:39:50.473334800 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -156,10 +156,15 @@ } } +const char* JfrRepository::path() { + return instance()._path; +} + bool JfrRepository::open_chunk(bool vm_error /* false */) { if (vm_error) { - ResourceMark rm; - _chunkwriter->set_path(JfrEmergencyDump::build_dump_path(_path)); + char chunk_path[JVM_MAXPATHLEN]; + JfrEmergencyDump::build_dump_path(_path, chunk_path, JVM_MAXPATHLEN); + _chunkwriter->set_path(chunk_path); } return _chunkwriter->open(); } --- old/src/hotspot/share/jfr/recorder/repository/jfrRepository.hpp 2020-02-11 22:39:53.897674700 +0900 +++ new/src/hotspot/share/jfr/recorder/repository/jfrRepository.hpp 2020-02-11 22:39:53.165788900 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -69,6 +69,7 @@ public: static void set_path(jstring location, JavaThread* jt); + static const char* 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-02-11 22:39:56.377502200 +0900 +++ new/src/hotspot/share/utilities/vmError.cpp 2020-02-11 22:39:55.630468900 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -148,6 +148,34 @@ out->print_raw_cr("#"); } +#if INCLUDE_JFR +static void print_jfr_path(outputStream *out) { + if (out == NULL) { + return; + } + + const char* dump_path = Jfr::saved_emergency_dump_path(); + const char* repository_path = Jfr::repository_path(); + if ((*dump_path == '\0') && + ((repository_path == NULL) || (*repository_path == '\0'))) { + return; + } + + out->print_raw_cr("# JFR recording file will be written. Location:"); + + if (*dump_path != '\0') { + out->print_raw("# - "); + out->print_raw_cr(dump_path); + } + if ((repository_path != NULL) && (*repository_path != '\0')) { + out->print_raw("# - "); + out->print_raw_cr(repository_path); + } + + out->print_raw_cr("#"); +} +#endif + bool VMError::coredump_status; char VMError::coredump_message[O_BUFLEN]; @@ -618,6 +646,13 @@ 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) { @@ -1404,6 +1439,7 @@ } os::check_dump_limit(buffer, sizeof(buffer)); + JFR_ONLY(Jfr::setup_emergency_dump_file_descriptor();) // reset signal handlers or exception filter; make sure recursive crashes // are handled properly. @@ -1415,8 +1451,6 @@ e.commit(); } - JFR_ONLY(Jfr::on_vm_shutdown(true);) - } else { // If UseOsErrorReporting we call this for each level of the call stack // while searching for the exception handler. Only the first level needs @@ -1538,6 +1572,8 @@ log.set_fd(-1); } + JFR_ONLY(Jfr::on_vm_shutdown(true);) + if (PrintNMTStatistics) { fdStream fds(fd_out); MemTracker::final_report(&fds);