Skip to content

Commit 3234ae2

Browse files
author
duke
committed
Backport f4209dff3ba14ccbdc0846d9bfcc62688361b6d5
1 parent a1206f0 commit 3234ae2

8 files changed

Lines changed: 157 additions & 41 deletions

File tree

src/hotspot/os/windows/os_windows.cpp

Lines changed: 15 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2628,14 +2628,13 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
26282628
DWORD exception_code = exception_record->ExceptionCode;
26292629
#if defined(_M_ARM64)
26302630
address pc = (address) exceptionInfo->ContextRecord->Pc;
2631+
2632+
if (handle_safefetch(exception_code, pc, (void*)exceptionInfo->ContextRecord)) {
2633+
return EXCEPTION_CONTINUE_EXECUTION;
2634+
}
26312635
#elif defined(_M_AMD64)
26322636
address pc = (address) exceptionInfo->ContextRecord->Rip;
2633-
#else
2634-
#error unknown architecture
2635-
#endif
2636-
Thread* t = Thread::current_or_null_safe();
26372637

2638-
#if defined(_M_AMD64)
26392638
if ((exception_code == EXCEPTION_ACCESS_VIOLATION) &&
26402639
VM_Version::is_cpuinfo_segv_addr(pc)) {
26412640
// Verify that OS save/restore AVX registers.
@@ -2648,6 +2647,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
26482647
VM_Version::clear_apx_test_state();
26492648
return Handle_Exception(exceptionInfo, VM_Version::cpuinfo_cont_addr_apx());
26502649
}
2650+
#else
2651+
#error unknown architecture
26512652
#endif
26522653

26532654
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
@@ -2658,6 +2659,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
26582659
}
26592660
#endif
26602661

2662+
Thread* t = Thread::current_or_null_safe();
26612663
if (t != nullptr && t->is_Java_thread()) {
26622664
JavaThread* thread = JavaThread::cast(t);
26632665
bool in_java = thread->thread_state() == _thread_in_Java;
@@ -2688,10 +2690,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
26882690
// Fatal red zone violation.
26892691
overflow_state->disable_stack_red_zone();
26902692
tty->print_raw_cr("An unrecoverable stack overflow has occurred.");
2691-
#if !defined(USE_VECTORED_EXCEPTION_HANDLING)
26922693
report_error(t, exception_code, pc, exception_record,
26932694
exceptionInfo->ContextRecord);
2694-
#endif
26952695
return EXCEPTION_CONTINUE_SEARCH;
26962696
}
26972697
} else if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
@@ -2743,10 +2743,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
27432743
}
27442744

27452745
// Stack overflow or null pointer exception in native code.
2746-
#if !defined(USE_VECTORED_EXCEPTION_HANDLING)
27472746
report_error(t, exception_code, pc, exception_record,
27482747
exceptionInfo->ContextRecord);
2749-
#endif
27502748
return EXCEPTION_CONTINUE_SEARCH;
27512749
} // /EXCEPTION_ACCESS_VIOLATION
27522750
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -2821,41 +2819,21 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
28212819
}
28222820
}
28232821

2824-
#if !defined(USE_VECTORED_EXCEPTION_HANDLING)
2825-
if (exception_code != EXCEPTION_BREAKPOINT) {
2826-
report_error(t, exception_code, pc, exception_record,
2827-
exceptionInfo->ContextRecord);
2828-
}
2829-
#endif
2830-
return EXCEPTION_CONTINUE_SEARCH;
2831-
}
2822+
bool should_report_error = (exception_code != EXCEPTION_BREAKPOINT);
28322823

2833-
#if defined(USE_VECTORED_EXCEPTION_HANDLING)
2834-
LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2835-
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
28362824
#if defined(_M_ARM64)
2837-
address pc = (address) exceptionInfo->ContextRecord->Pc;
2838-
#elif defined(_M_AMD64)
2839-
address pc = (address) exceptionInfo->ContextRecord->Rip;
2840-
#else
2841-
#error unknown architecture
2825+
should_report_error = should_report_error &&
2826+
FAILED(exception_code) &&
2827+
(exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION);
28422828
#endif
28432829

2844-
// Fast path for code part of the code cache
2845-
if (CodeCache::low_bound() <= pc && pc < CodeCache::high_bound()) {
2846-
return topLevelExceptionFilter(exceptionInfo);
2847-
}
2848-
2849-
// If the exception occurred in the codeCache, pass control
2850-
// to our normal exception handler.
2851-
CodeBlob* cb = CodeCache::find_blob(pc);
2852-
if (cb != nullptr) {
2853-
return topLevelExceptionFilter(exceptionInfo);
2830+
if (should_report_error) {
2831+
report_error(t, exception_code, pc, exception_record,
2832+
exceptionInfo->ContextRecord);
28542833
}
28552834

28562835
return EXCEPTION_CONTINUE_SEARCH;
28572836
}
2858-
#endif
28592837

28602838
#if defined(USE_VECTORED_EXCEPTION_HANDLING)
28612839
LONG WINAPI topLevelUnhandledExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
@@ -4488,7 +4466,7 @@ jint os::init_2(void) {
44884466
// Setup Windows Exceptions
44894467

44904468
#if defined(USE_VECTORED_EXCEPTION_HANDLING)
4491-
topLevelVectoredExceptionHandler = AddVectoredExceptionHandler(1, topLevelVectoredExceptionFilter);
4469+
topLevelVectoredExceptionHandler = AddVectoredExceptionHandler(1, topLevelExceptionFilter);
44924470
previousUnhandledExceptionFilter = SetUnhandledExceptionFilter(topLevelUnhandledExceptionFilter);
44934471
#endif
44944472

src/hotspot/os/windows/os_windows.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ class os::win32 {
150150
// signal support
151151
static void* install_signal_handler(int sig, signal_handler_t handler);
152152
static void* user_handler();
153+
154+
static void context_set_pc(CONTEXT* uc, address pc);
153155
};
154156

155157
#endif // OS_WINDOWS_OS_WINDOWS_HPP
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (c) 2022 SAP SE. All rights reserved.
3+
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation.
9+
*
10+
* This code is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* version 2 for more details (a copy is included in the LICENSE file that
14+
* accompanied this code).
15+
*
16+
* You should have received a copy of the GNU General Public License version
17+
* 2 along with this work; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*
20+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21+
* or visit www.oracle.com if you need additional information or have any
22+
* questions.
23+
*
24+
*/
25+
26+
27+
#include "os_windows.hpp"
28+
#include "runtime/os.hpp"
29+
#include "runtime/safefetch.hpp"
30+
#include "utilities/globalDefinitions.hpp"
31+
32+
#ifdef SAFEFETCH_METHOD_STATIC_ASSEMBLY
33+
34+
// SafeFetch handling, static assembly style:
35+
//
36+
// SafeFetch32 and SafeFetchN are implemented via static assembly
37+
// and live in os_cpu/xx_xx/safefetch_xx_xx.S
38+
39+
extern "C" char _SafeFetch32_continuation[];
40+
extern "C" char _SafeFetch32_fault[];
41+
42+
#ifdef _LP64
43+
extern "C" char _SafeFetchN_continuation[];
44+
extern "C" char _SafeFetchN_fault[];
45+
#endif // _LP64
46+
47+
bool handle_safefetch(int exception_code, address pc, void* context) {
48+
CONTEXT* ctx = (CONTEXT*)context;
49+
if (exception_code == EXCEPTION_ACCESS_VIOLATION && ctx != nullptr) {
50+
if (pc == (address)_SafeFetch32_fault) {
51+
os::win32::context_set_pc(ctx, (address)_SafeFetch32_continuation);
52+
return true;
53+
}
54+
#ifdef _LP64
55+
if (pc == (address)_SafeFetchN_fault) {
56+
os::win32::context_set_pc(ctx, (address)_SafeFetchN_continuation);
57+
return true;
58+
}
59+
#endif
60+
}
61+
return false;
62+
}
63+
64+
#endif // SAFEFETCH_METHOD_STATIC_ASSEMBLY

src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ intptr_t* os::fetch_bcp_from_context(const void* ucVoid) {
115115
return reinterpret_cast<intptr_t*>(uc->REG_BCP);
116116
}
117117

118+
void os::win32::context_set_pc(CONTEXT* uc, address pc) {
119+
uc->Pc = (intptr_t)pc;
120+
}
121+
118122
bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread,
119123
struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) {
120124
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
;
2+
; Copyright (c) 2022 SAP SE. All rights reserved.
3+
; Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
4+
; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
;
6+
; This code is free software; you can redistribute it and/or modify it
7+
; under the terms of the GNU General Public License version 2 only, as
8+
; published by the Free Software Foundation.
9+
;
10+
; This code is distributed in the hope that it will be useful, but WITHOUT
11+
; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
; version 2 for more details (a copy is included in the LICENSE file that
14+
; accompanied this code).
15+
;
16+
; You should have received a copy of the GNU General Public License version
17+
; 2 along with this work; if not, write to the Free Software Foundation,
18+
; Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19+
;
20+
; Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21+
; or visit www.oracle.com if you need additional information or have any
22+
; questions.
23+
;
24+
25+
; Support for int SafeFetch32(int* address, int defaultval);
26+
;
27+
; x0 : address
28+
; w1 : defaultval
29+
30+
; needed to align function start to 4 byte
31+
ALIGN 4
32+
EXPORT _SafeFetch32_fault
33+
EXPORT _SafeFetch32_continuation
34+
EXPORT SafeFetch32_impl
35+
AREA safefetch_text, CODE
36+
37+
SafeFetch32_impl
38+
_SafeFetch32_fault
39+
ldr w0, [x0]
40+
ret
41+
42+
_SafeFetch32_continuation
43+
mov x0, x1
44+
ret
45+
46+
; Support for intptr_t SafeFetchN(intptr_t* address, intptr_t defaultval);
47+
;
48+
; x0 : address
49+
; x1 : defaultval
50+
51+
ALIGN 4
52+
EXPORT _SafeFetchN_fault
53+
EXPORT _SafeFetchN_continuation
54+
EXPORT SafeFetchN_impl
55+
56+
SafeFetchN_impl
57+
_SafeFetchN_fault
58+
ldr x0, [x0]
59+
ret
60+
61+
_SafeFetchN_continuation
62+
mov x0, x1
63+
ret
64+
65+
END

src/hotspot/share/runtime/safefetch.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
// Safefetch allows to load a value from a location that's not known
3232
// to be valid. If the load causes a fault, the error value is returned.
3333

34-
#ifdef _WIN32
35-
// Windows uses Structured Exception Handling
34+
#if defined(_WIN32) && !defined(_M_ARM64)
35+
// Windows x86_64 uses Structured Exception Handling
3636
#include "safefetch_windows.hpp"
3737
#elif defined(ZERO) || defined (_AIX)
3838
// These platforms implement safefetch via Posix sigsetjmp/longjmp.

test/hotspot/jtreg/runtime/ErrorHandling/UncaughtNativeExceptionTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public void testNativeExceptionReporting() throws Exception {
6464
assertTrue(Files.exists(hsErrPath));
6565

6666
Pattern[] positivePatterns = {
67-
Pattern.compile(".*Internal Error \\(0x2a\\).*")
67+
Pattern.compile(".*Internal Error \\(0xdeadbeef\\).*")
6868
};
6969
HsErrFileUtils.checkHsErrFileContent(hsErrFile, positivePatterns, null, true /* check end marker */, false /* verbose */);
7070
}

test/hotspot/jtreg/runtime/ErrorHandling/libNativeException.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@
2525

2626
#include <Windows.h>
2727

28-
const DWORD EX_CODE = 42;
28+
// Use an exception code that causes the Windows FAILED() macro to return true.
29+
// Windows AArch64 uses vectored exception handling and therefore runs error
30+
// reporting only for failed exception codes.
31+
const DWORD EX_CODE = 0xdeadbeef;
2932

3033
JNIEXPORT void JNICALL Java_UncaughtNativeExceptionTest_00024Crasher_throwException(JNIEnv* env, jclass cls) {
3134
RaiseException(EX_CODE, EXCEPTION_NONCONTINUABLE, 0, NULL);

0 commit comments

Comments
 (0)