8348862: runtime/ErrorHandling/CreateCoredumpOnCrash fails on Windows aarch64

Reviewed-by: dholmes, mbeckwit
This commit is contained in:
Saint Wesonga 2025-10-10 03:55:47 +00:00 committed by David Holmes
parent 2311ec394d
commit f4209dff3b
8 changed files with 159 additions and 43 deletions

View File

@ -2630,14 +2630,13 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
DWORD exception_code = exception_record->ExceptionCode;
#if defined(_M_ARM64)
address pc = (address) exceptionInfo->ContextRecord->Pc;
if (handle_safefetch(exception_code, pc, (void*)exceptionInfo->ContextRecord)) {
return EXCEPTION_CONTINUE_EXECUTION;
}
#elif defined(_M_AMD64)
address pc = (address) exceptionInfo->ContextRecord->Rip;
#else
#error unknown architecture
#endif
Thread* t = Thread::current_or_null_safe();
#if defined(_M_AMD64)
if ((exception_code == EXCEPTION_ACCESS_VIOLATION) &&
VM_Version::is_cpuinfo_segv_addr(pc)) {
// Verify that OS save/restore AVX registers.
@ -2650,6 +2649,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
VM_Version::clear_apx_test_state();
return Handle_Exception(exceptionInfo, VM_Version::cpuinfo_cont_addr_apx());
}
#else
#error unknown architecture
#endif
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
@ -2660,6 +2661,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
}
#endif
Thread* t = Thread::current_or_null_safe();
if (t != nullptr && t->is_Java_thread()) {
JavaThread* thread = JavaThread::cast(t);
bool in_java = thread->thread_state() == _thread_in_Java;
@ -2690,10 +2692,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
// Fatal red zone violation.
overflow_state->disable_stack_red_zone();
tty->print_raw_cr("An unrecoverable stack overflow has occurred.");
#if !defined(USE_VECTORED_EXCEPTION_HANDLING)
report_error(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
#endif
return EXCEPTION_CONTINUE_SEARCH;
}
} else if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
@ -2745,10 +2745,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
}
// Stack overflow or null pointer exception in native code.
#if !defined(USE_VECTORED_EXCEPTION_HANDLING)
report_error(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
#endif
return EXCEPTION_CONTINUE_SEARCH;
} // /EXCEPTION_ACCESS_VIOLATION
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -2808,41 +2806,21 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
}
}
#if !defined(USE_VECTORED_EXCEPTION_HANDLING)
if (exception_code != EXCEPTION_BREAKPOINT) {
bool should_report_error = (exception_code != EXCEPTION_BREAKPOINT);
#if defined(_M_ARM64)
should_report_error = should_report_error &&
FAILED(exception_code) &&
(exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION);
#endif
if (should_report_error) {
report_error(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
}
#endif
return EXCEPTION_CONTINUE_SEARCH;
}
#if defined(USE_VECTORED_EXCEPTION_HANDLING)
LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
#if defined(_M_ARM64)
address pc = (address) exceptionInfo->ContextRecord->Pc;
#elif defined(_M_AMD64)
address pc = (address) exceptionInfo->ContextRecord->Rip;
#else
#error unknown architecture
#endif
// Fast path for code part of the code cache
if (CodeCache::low_bound() <= pc && pc < CodeCache::high_bound()) {
return topLevelExceptionFilter(exceptionInfo);
}
// If the exception occurred in the codeCache, pass control
// to our normal exception handler.
CodeBlob* cb = CodeCache::find_blob(pc);
if (cb != nullptr) {
return topLevelExceptionFilter(exceptionInfo);
}
return EXCEPTION_CONTINUE_SEARCH;
}
#endif
#if defined(USE_VECTORED_EXCEPTION_HANDLING)
LONG WINAPI topLevelUnhandledExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
@ -4519,7 +4497,7 @@ jint os::init_2(void) {
// Setup Windows Exceptions
#if defined(USE_VECTORED_EXCEPTION_HANDLING)
topLevelVectoredExceptionHandler = AddVectoredExceptionHandler(1, topLevelVectoredExceptionFilter);
topLevelVectoredExceptionHandler = AddVectoredExceptionHandler(1, topLevelExceptionFilter);
previousUnhandledExceptionFilter = SetUnhandledExceptionFilter(topLevelUnhandledExceptionFilter);
#endif

View File

@ -150,6 +150,8 @@ public:
// signal support
static void* install_signal_handler(int sig, signal_handler_t handler);
static void* user_handler();
static void context_set_pc(CONTEXT* uc, address pc);
};
#endif // OS_WINDOWS_OS_WINDOWS_HPP

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2022 SAP SE. All rights reserved.
* Copyright (c) 2022, 2025, 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.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "os_windows.hpp"
#include "runtime/os.hpp"
#include "runtime/safefetch.hpp"
#include "utilities/globalDefinitions.hpp"
#ifdef SAFEFETCH_METHOD_STATIC_ASSEMBLY
// SafeFetch handling, static assembly style:
//
// SafeFetch32 and SafeFetchN are implemented via static assembly
// and live in os_cpu/xx_xx/safefetch_xx_xx.S
extern "C" char _SafeFetch32_continuation[];
extern "C" char _SafeFetch32_fault[];
#ifdef _LP64
extern "C" char _SafeFetchN_continuation[];
extern "C" char _SafeFetchN_fault[];
#endif // _LP64
bool handle_safefetch(int exception_code, address pc, void* context) {
CONTEXT* ctx = (CONTEXT*)context;
if (exception_code == EXCEPTION_ACCESS_VIOLATION && ctx != nullptr) {
if (pc == (address)_SafeFetch32_fault) {
os::win32::context_set_pc(ctx, (address)_SafeFetch32_continuation);
return true;
}
#ifdef _LP64
if (pc == (address)_SafeFetchN_fault) {
os::win32::context_set_pc(ctx, (address)_SafeFetchN_continuation);
return true;
}
#endif
}
return false;
}
#endif // SAFEFETCH_METHOD_STATIC_ASSEMBLY

View File

@ -115,6 +115,10 @@ intptr_t* os::fetch_bcp_from_context(const void* ucVoid) {
return reinterpret_cast<intptr_t*>(uc->REG_BCP);
}
void os::win32::context_set_pc(CONTEXT* uc, address pc) {
uc->Pc = (intptr_t)pc;
}
bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread,
struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) {
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;

View File

@ -0,0 +1,65 @@
;
; Copyright (c) 2022 SAP SE. All rights reserved.
; Copyright (c) 2022, 2025, 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.
;
; This code is distributed in the hope that it will be useful, but WITHOUT
; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
; version 2 for more details (a copy is included in the LICENSE file that
; accompanied this code).
;
; You should have received a copy of the GNU General Public License version
; 2 along with this work; if not, write to the Free Software Foundation,
; Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
;
; Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
; or visit www.oracle.com if you need additional information or have any
; questions.
;
; Support for int SafeFetch32(int* address, int defaultval);
;
; x0 : address
; w1 : defaultval
; needed to align function start to 4 byte
ALIGN 4
EXPORT _SafeFetch32_fault
EXPORT _SafeFetch32_continuation
EXPORT SafeFetch32_impl
AREA safefetch_text, CODE
SafeFetch32_impl
_SafeFetch32_fault
ldr w0, [x0]
ret
_SafeFetch32_continuation
mov x0, x1
ret
; Support for intptr_t SafeFetchN(intptr_t* address, intptr_t defaultval);
;
; x0 : address
; x1 : defaultval
ALIGN 4
EXPORT _SafeFetchN_fault
EXPORT _SafeFetchN_continuation
EXPORT SafeFetchN_impl
SafeFetchN_impl
_SafeFetchN_fault
ldr x0, [x0]
ret
_SafeFetchN_continuation
mov x0, x1
ret
END

View File

@ -31,8 +31,8 @@
// Safefetch allows to load a value from a location that's not known
// to be valid. If the load causes a fault, the error value is returned.
#ifdef _WIN32
// Windows uses Structured Exception Handling
#if defined(_WIN32) && !defined(_M_ARM64)
// Windows x86_64 uses Structured Exception Handling
#include "safefetch_windows.hpp"
#elif defined(ZERO) || defined (_AIX)
// These platforms implement safefetch via Posix sigsetjmp/longjmp.

View File

@ -64,7 +64,7 @@ public class UncaughtNativeExceptionTest {
assertTrue(Files.exists(hsErrPath));
Pattern[] positivePatterns = {
Pattern.compile(".*Internal Error \\(0x2a\\).*")
Pattern.compile(".*Internal Error \\(0xdeadbeef\\).*")
};
HsErrFileUtils.checkHsErrFileContent(hsErrFile, positivePatterns, null, true /* check end marker */, false /* verbose */);
}

View File

@ -25,7 +25,10 @@
#include <Windows.h>
const DWORD EX_CODE = 42;
// Use an exception code that causes the Windows FAILED() macro to return true.
// Windows AArch64 uses vectored exception handling and therefore runs error
// reporting only for failed exception codes.
const DWORD EX_CODE = 0xdeadbeef;
JNIEXPORT void JNICALL Java_UncaughtNativeExceptionTest_00024Crasher_throwException(JNIEnv* env, jclass cls) {
RaiseException(EX_CODE, EXCEPTION_NONCONTINUABLE, 0, NULL);