Skip to content
Permalink
Browse files
8269416: [JVMCI] capture libjvmci crash data to a file
Reviewed-by: kvn, dholmes
  • Loading branch information
Doug Simon committed Jun 30, 2021
1 parent a0f32cb commit a6b253d85c732ddd1d3154d5fc108d2bba66ab01
Showing 7 changed files with 96 additions and 3 deletions.
@@ -34,6 +34,7 @@
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "runtime/arguments.hpp"
#include "runtime/atomic.hpp"
#include "utilities/events.hpp"

JVMCIRuntime* JVMCI::_compiler_runtime = NULL;
@@ -45,6 +46,9 @@ char* JVMCI::_shared_library_path = NULL;
volatile bool JVMCI::_in_shutdown = false;
StringEventLog* JVMCI::_events = NULL;
StringEventLog* JVMCI::_verbose_events = NULL;
volatile intx JVMCI::_fatal_log_init_thread = -1;
volatile int JVMCI::_fatal_log_fd = -1;
const char* JVMCI::_fatal_log_filename = NULL;

void jvmci_vmStructs_init() NOT_DEBUG_RETURN;

@@ -211,6 +215,45 @@ bool JVMCI::in_shutdown() {
return _in_shutdown;
}

void JVMCI::fatal_log(const char* buf, size_t count) {
intx current_thread_id = os::current_thread_id();
intx invalid_id = -1;
int log_fd;
if (_fatal_log_init_thread == invalid_id && Atomic::cmpxchg(&_fatal_log_init_thread, invalid_id, current_thread_id) == invalid_id) {
if (ErrorFileToStdout) {
log_fd = 1;
} else if (ErrorFileToStderr) {
log_fd = 2;
} else {
static char name_buffer[O_BUFLEN];
log_fd = VMError::prepare_log_file(JVMCINativeLibraryErrorFile, LIBJVMCI_ERR_FILE, true, name_buffer, sizeof(name_buffer));
if (log_fd != -1) {
_fatal_log_filename = name_buffer;
} else {
int e = errno;
tty->print("Can't open JVMCI shared library error report file. Error: ");
tty->print_raw_cr(os::strerror(e));
tty->print_cr("JVMCI shared library error report will be written to console.");

// See notes in VMError::report_and_die about hard coding tty to 1
log_fd = 1;
}
}
_fatal_log_fd = log_fd;
} else {
// Another thread won the race to initialize the stream. Give it time
// to complete initialization. VM locks cannot be used as the current
// thread might not be attached to the VM (e.g. a native thread started
// within libjvmci).
while (_fatal_log_fd == -1) {
os::naked_short_sleep(50);
}
}
fdStream log(_fatal_log_fd);
log.write(buf, count);
log.flush();
}

void JVMCI::vlog(int level, const char* format, va_list ap) {
if (LogEvents && JVMCIEventLogLevel >= level) {
StringEventLog* events = level == 1 ? _events : _verbose_events;
@@ -74,6 +74,16 @@ class JVMCI : public AllStatic {
// Access to the HotSpot heap based JVMCIRuntime
static JVMCIRuntime* _java_runtime;

// The file descriptor to which fatal_log() writes. Initialized on
// first call to fatal_log().
static volatile int _fatal_log_fd;

// The path of the file underlying _fatal_log_fd if it is a normal file.
static const char* _fatal_log_filename;

// Native thread id of thread that will initialize _fatal_log_fd.
static volatile intx _fatal_log_init_thread;

// JVMCI event log (shows up in hs_err crash logs).
static StringEventLog* _events;
static StringEventLog* _verbose_events;
@@ -100,6 +110,13 @@ class JVMCI : public AllStatic {
// `load` is true then JVMCI_lock must be locked.
static void* get_shared_library(char*& path, bool load);

// Logs the fatal crash data in `buf` to the appropriate stream.
static void fatal_log(const char* buf, size_t count);

// Gets the name of the opened JVMCI shared library crash data file or NULL
// if this file has not been created.
static const char* fatal_log_filename() { return _fatal_log_filename; }

static void do_unloading(bool unloading_occurred);

static void metadata_do(void f(Metadata*));
@@ -891,14 +891,21 @@ static void _log(const char* buf, size_t count) {
tty->write((char*) buf, count);
}

// Function for redirecting shared library JavaVM fatal error data to a log file.
// The log file is opened on first call to this function.
static void _fatal_log(const char* buf, size_t count) {
JVMCI::fatal_log(buf, count);
}

// Function for shared library JavaVM to flush tty
static void _flush_log() {
tty->flush();
}

// Function for shared library JavaVM to exit HotSpot on a fatal error
static void _fatal() {
fatal("Fatal error in JVMCI shared library");
intx current_thread_id = os::current_thread_id();
fatal("thread " INTX_FORMAT ": Fatal error in JVMCI shared library", current_thread_id);
}

JNIEnv* JVMCIRuntime::init_shared_library_javavm() {
@@ -925,7 +932,7 @@ JNIEnv* JVMCIRuntime::init_shared_library_javavm() {
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_2;
vm_args.ignoreUnrecognized = JNI_TRUE;
JavaVMOption options[4];
JavaVMOption options[5];
jlong javaVM_id = 0;

// Protocol: JVMCI shared library JavaVM should support a non-standard "_javavm_id"
@@ -940,6 +947,8 @@ JNIEnv* JVMCIRuntime::init_shared_library_javavm() {
options[2].extraInfo = (void*) _flush_log;
options[3].optionString = (char*) "_fatal";
options[3].extraInfo = (void*) _fatal;
options[4].optionString = (char*) "_fatal_log";
options[4].extraInfo = (void*) _fatal_log;

vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
@@ -121,6 +121,7 @@ bool JVMCIGlobals::check_jvmci_flags_are_consistent() {
CHECK_NOT_SET(JVMCIPrintProperties, EnableJVMCI)
CHECK_NOT_SET(UseJVMCINativeLibrary, EnableJVMCI)
CHECK_NOT_SET(JVMCILibPath, EnableJVMCI)
CHECK_NOT_SET(JVMCINativeLibraryErrorFile, EnableJVMCI)
CHECK_NOT_SET(JVMCILibDumpJNIConfig, EnableJVMCI)

#ifndef COMPILER2
@@ -176,6 +177,7 @@ bool JVMCIGlobals::enable_jvmci_product_mode(JVMFlagOrigin origin) {
"JVMCILibPath",
"JVMCILibDumpJNIConfig",
"UseJVMCINativeLibrary",
"JVMCINativeLibraryErrorFile",
NULL
};

@@ -30,6 +30,8 @@

class fileStream;

#define LIBJVMCI_ERR_FILE "hs_err_pid%p_libjvmci.log"

//
// Declare all global flags used by the JVMCI compiler. Only flags that need
// to be accessible to the JVMCI C++ code should be defined here.
@@ -123,6 +125,11 @@ class fileStream;
"on the HotSpot heap. Defaults to true if EnableJVMCIProduct is " \
"true and a JVMCI native library is available.") \
\
product(ccstr, JVMCINativeLibraryErrorFile, NULL, EXPERIMENTAL, \
"If an error in the JVMCI native library occurs, save the " \
"error data to this file" \
"[default: ./" LIBJVMCI_ERR_FILE "] (%p replaced with pid)") \
\
NOT_COMPILER2(product(bool, UseMultiplyToLenIntrinsic, false, DIAGNOSTIC, \
"Enables intrinsification of BigInteger.multiplyToLen()")) \
\
@@ -63,6 +63,9 @@
#if INCLUDE_JFR
#include "jfr/jfr.hpp"
#endif
#if INCLUDE_JVMCI
#include "jvmci/jvmci.hpp"
#endif

#ifndef PRODUCT
#include <signal.h>
@@ -1273,7 +1276,7 @@ static int expand_and_open(const char* pattern, bool overwrite_existing, char* b
* Name and location depends on pattern, default_pattern params and access
* permissions.
*/
static int prepare_log_file(const char* pattern, const char* default_pattern, bool overwrite_existing, char* buf, size_t buflen) {
int VMError::prepare_log_file(const char* pattern, const char* default_pattern, bool overwrite_existing, char* buf, size_t buflen) {
int fd = -1;

// If possible, use specified pattern to construct log file name
@@ -1584,6 +1587,13 @@ void VMError::report_and_die(int id, const char* message, const char* detail_fmt
}
}

#if INCLUDE_JVMCI
if (JVMCI::fatal_log_filename() != NULL) {
out.print_raw("#\n# The JVMCI shared library error report file is saved as:\n# ");
out.print_raw_cr(JVMCI::fatal_log_filename());
}
#endif

static bool skip_bug_url = !should_submit_bug_report(_id);
if (!skip_bug_url) {
skip_bug_url = true;
@@ -184,5 +184,10 @@ class VMError : public AllStatic {
// Needed when printing signal handlers.
NOT_WINDOWS(static const void* crash_handler_address;)

// Construct file name for a log file and return it's file descriptor.
// Name and location depends on pattern, default_pattern params and access
// permissions.
static int prepare_log_file(const char* pattern, const char* default_pattern, bool overwrite_existing, char* buf, size_t buflen);

};
#endif // SHARE_UTILITIES_VMERROR_HPP

1 comment on commit a6b253d

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on a6b253d Jun 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.