8302798: Refactor -XX:+UseOSErrorReporting for noreturn crash reporting

Reviewed-by: coleenp, stuefe
This commit is contained in:
Kim Barrett 2023-03-01 10:19:28 +00:00
parent 6b07243f56
commit 539a4951ee
5 changed files with 44 additions and 30 deletions
src/hotspot

@ -2023,9 +2023,10 @@ void os::die() {
// For TimeoutInErrorHandlingTest.java, we just kill the VM
// and don't take the time to generate a core file.
::raise(SIGKILL);
} else {
::abort();
// ::raise is not noreturn, even though with SIGKILL it definitely won't
// return. Hence "fall through" to ::abort, which is declared noreturn.
}
::abort();
}
const char* os::file_separator() { return "/"; }

@ -66,3 +66,9 @@ void VMError::check_failing_cds_access(outputStream* st, const void* siginfo) {
void VMError::reporting_started() {}
void VMError::interrupt_reporting_thread() {}
void VMError::raise_fail_fast(void* exrecord, void* context) {
DWORD flags = (exrecord == nullptr) ? FAIL_FAST_GENERATE_EXCEPTION_ADDRESS : 0;
RaiseFailFastException(static_cast<PEXCEPTION_RECORD>(exrecord),
static_cast<PCONTEXT>(context),
flags);
}

@ -576,7 +576,7 @@ class os: AllStatic {
// multiple calls to naked_short_sleep. Only for use by non-JavaThreads.
static void naked_sleep(jlong millis);
// Never returns, use with CAUTION
static void infinite_sleep();
[[noreturn]] static void infinite_sleep();
static void naked_yield () ;
static OSReturn set_priority(Thread* thread, ThreadPriority priority);
static OSReturn get_priority(const Thread* const thread, ThreadPriority& priority);
@ -601,26 +601,26 @@ class os: AllStatic {
static int fork_and_exec(const char *cmd);
// Call ::exit() on all platforms
static void exit(int num);
[[noreturn]] static void exit(int num);
// Call ::_exit() on all platforms. Similar semantics to die() except we never
// want a core dump.
static void _exit(int num);
[[noreturn]] static void _exit(int num);
// Terminate the VM, but don't exit the process
static void shutdown();
// Terminate with an error. Default is to generate a core file on platforms
// that support such things. This calls shutdown() and then aborts.
static void abort(bool dump_core, void *siginfo, const void *context);
static void abort(bool dump_core = true);
[[noreturn]] static void abort(bool dump_core, void *siginfo, const void *context);
[[noreturn]] static void abort(bool dump_core = true);
// Die immediately, no exit hook, no abort hook, no cleanup.
// Dump a core file, if possible, for debugging. os::abort() is the
// preferred means to abort the VM on error. os::die() should only
// be called if something has gone badly wrong. CreateCoredumpOnCrash
// is intentionally not honored by this function.
static void die();
[[noreturn]] static void die();
// File i/o operations
static int open(const char *path, int oflag, int mode);

@ -1442,13 +1442,6 @@ void VMError::report_and_die(int id, const char* message, const char* detail_fmt
// are handled properly.
install_secondary_signal_handler();
} else {
#if defined(_WINDOWS)
// If UseOSErrorReporting we call this for each level of the call stack
// while searching for the exception handler. Only the first level needs
// to be reported.
if (UseOSErrorReporting && log_done) return;
#endif
// This is not the first error, see if it happened in a different thread
// or in the same thread during error reporting.
if (_first_error_tid != mytid) {
@ -1678,18 +1671,21 @@ void VMError::report_and_die(int id, const char* message, const char* detail_fmt
OnError = nullptr;
}
if (WINDOWS_ONLY(!UseOSErrorReporting) NOT_WINDOWS(true)) {
// os::abort() will call abort hooks, try it first.
static bool skip_os_abort = false;
if (!skip_os_abort) {
skip_os_abort = true;
bool dump_core = should_report_bug(_id);
os::abort(dump_core && CreateCoredumpOnCrash, _siginfo, _context);
}
// if os::abort() doesn't abort, try os::die();
os::die();
#if defined _WINDOWS
if (UseOSErrorReporting) {
raise_fail_fast(_siginfo, _context);
}
#endif // _WINDOWS
// os::abort() will call abort hooks, try it first.
static bool skip_os_abort = false;
if (!skip_os_abort) {
skip_os_abort = true;
bool dump_core = should_report_bug(_id);
os::abort(dump_core && CreateCoredumpOnCrash, _siginfo, _context);
// if os::abort() doesn't abort, try os::die();
}
os::die();
}
/*

@ -136,6 +136,8 @@ class VMError : public AllStatic {
static jlong get_step_start_time();
static void clear_step_start_time();
WINDOWS_ONLY([[noreturn]] static void raise_fail_fast(void* exrecord, void* context);)
public:
// print_source_info: if true, we try to resolve the source information on platforms that support it
@ -154,22 +156,31 @@ public:
static void print_vm_info(outputStream* st);
// main error reporting function
[[noreturn]]
ATTRIBUTE_PRINTF(6, 7)
static void report_and_die(Thread* thread, unsigned int sig, address pc, void* siginfo,
void* context, const char* detail_fmt, ...) ATTRIBUTE_PRINTF(6, 7);
void* context, const char* detail_fmt, ...);
[[noreturn]]
ATTRIBUTE_PRINTF(3, 0)
static void report_and_die(int id, const char* message, const char* detail_fmt, va_list detail_args,
Thread* thread, address pc, void* siginfo, void* context,
const char* filename, int lineno, size_t size) ATTRIBUTE_PRINTF(3, 0);
const char* filename, int lineno, size_t size);
[[noreturn]]
static void report_and_die(Thread* thread, unsigned int sig, address pc,
void* siginfo, void* context);
[[noreturn]]
ATTRIBUTE_PRINTF(6, 0)
static void report_and_die(Thread* thread, void* context, const char* filename, int lineno, const char* message,
const char* detail_fmt, va_list detail_args) ATTRIBUTE_PRINTF(6, 0);
const char* detail_fmt, va_list detail_args);
[[noreturn]]
ATTRIBUTE_PRINTF(6, 0)
static void report_and_die(Thread* thread, const char* filename, int lineno, size_t size,
VMErrorType vm_err_type, const char* detail_fmt,
va_list detail_args) ATTRIBUTE_PRINTF(6, 0);
va_list detail_args);
// reporting OutOfMemoryError
static void report_java_out_of_memory(const char* message);