mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-19 04:13:07 +00:00
8348862: runtime/ErrorHandling/CreateCoredumpOnCrash fails on Windows aarch64
Reviewed-by: dholmes, mbeckwit
This commit is contained in:
parent
2311ec394d
commit
f4209dff3b
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
64
src/hotspot/os/windows/safefetch_static_windows.cpp
Normal file
64
src/hotspot/os/windows/safefetch_static_windows.cpp
Normal 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
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
@ -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.
|
||||
|
||||
@ -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 */);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user