< prev index next >
src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2012, 2019, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 38,52 ****
--- 38,55 ----
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#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);
}
*** 210,220 ****
const char* const RepositoryIterator::next() const {
return _iterator >= _files->length() ? NULL : fully_qualified(_files->at(_iterator++));
}
! static void write_emergency_file(fio_fd emergency_fd, 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);
if (file_copy_block == NULL) {
return;
--- 213,223 ----
const char* const RepositoryIterator::next() const {
return _iterator >= _files->length() ? NULL : fully_qualified(_files->at(_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);
if (file_copy_block == NULL) {
return;
*** 245,259 ****
}
}
}
}
! static const char* create_emergency_dump_path() {
! char* buffer = NEW_RESOURCE_ARRAY_RETURN_NULL(char, JVM_MAXPATHLEN);
! if (NULL == buffer) {
! return NULL;
! }
const char* const cwd = os::get_current_directory(buffer, JVM_MAXPATHLEN);
if (NULL == cwd) {
return NULL;
}
size_t pos = strlen(cwd);
--- 248,260 ----
}
}
}
}
! 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;
}
size_t pos = strlen(cwd);
*** 268,296 ****
filename_fmt = vm_soe_filename_fmt;
break;
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) {
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) {
assert(repository_path != NULL, "invariant");
const size_t repository_path_len = strlen(repository_path);
// date time
char date_time_buffer[32] = { 0 };
date_time(date_time_buffer, sizeof(date_time_buffer));
--- 269,294 ----
filename_fmt = vm_soe_filename_fmt;
break;
default:
filename_fmt = vm_error_filename_fmt;
}
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);
! if ((emergency_filename_length + 1) > len) { // includes NUL char
return NULL;
}
! strncpy(emergency_dump_path, buffer, len);
}
! 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;
}
! 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
char date_time_buffer[32] = { 0 };
date_time(date_time_buffer, sizeof(date_time_buffer));
*** 298,334 ****
size_t chunkname_max_len = repository_path_len // repository_base_path
+ 1 // "/"
+ 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;
}
! 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;
}
! const char* JfrEmergencyDump::build_dump_path(const char* repository_path) {
! return repository_path == NULL ? create_emergency_dump_path() : 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);
os::close(emergency_fd);
}
}
/*
* We are just about to exit the VM, so we will be very aggressive
--- 296,332 ----
size_t chunkname_max_len = repository_path_len // repository_base_path
+ 1 // "/"
+ date_time_len // date_time
+ strlen(chunk_file_jfr_ext) // .jfr
+ 1;
! if (chunk_path_len < chunkname_max_len) {
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;
}
! 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, 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;
if (emergency_fd != invalid_fd) {
RepositoryIterator iterator(repository_path, strlen(repository_path));
! write_emergency_file(iterator);
os::close(emergency_fd);
+ emergency_fd = invalid_fd;
}
}
/*
* We are just about to exit the VM, so we will be very aggressive
< prev index next >