@@ -2752,6 +2752,10 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
27522752 // Verify that OS save/restore AVX registers.
27532753 return Handle_Exception (exceptionInfo, VM_Version::cpuinfo_cont_addr ());
27542754 }
2755+ #elif defined(_M_ARM64)
2756+ if (handle_safefetch (exception_code, pc, (void *)exceptionInfo->ContextRecord )) {
2757+ return EXCEPTION_CONTINUE_EXECUTION;
2758+ }
27552759#endif
27562760
27572761 if (t != nullptr && t->is_Java_thread ()) {
@@ -2784,10 +2788,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
27842788 // Fatal red zone violation.
27852789 overflow_state->disable_stack_red_zone ();
27862790 tty->print_raw_cr (" An unrecoverable stack overflow has occurred." );
2787- #if !defined(USE_VECTORED_EXCEPTION_HANDLING)
27882791 report_error (t, exception_code, pc, exception_record,
27892792 exceptionInfo->ContextRecord );
2790- #endif
27912793 return EXCEPTION_CONTINUE_SEARCH;
27922794 }
27932795 } else if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
@@ -2843,10 +2845,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
28432845#endif
28442846
28452847 // Stack overflow or null pointer exception in native code.
2846- #if !defined(USE_VECTORED_EXCEPTION_HANDLING)
28472848 report_error (t, exception_code, pc, exception_record,
28482849 exceptionInfo->ContextRecord );
2849- #endif
28502850 return EXCEPTION_CONTINUE_SEARCH;
28512851 } // /EXCEPTION_ACCESS_VIOLATION
28522852 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -2920,41 +2920,21 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
29202920 }
29212921 }
29222922
2923- #if !defined(USE_VECTORED_EXCEPTION_HANDLING)
2924- if (exception_code != EXCEPTION_BREAKPOINT) {
2925- report_error (t, exception_code, pc, exception_record,
2926- exceptionInfo->ContextRecord );
2927- }
2928- #endif
2929- return EXCEPTION_CONTINUE_SEARCH;
2930- }
2923+ bool should_report_error = (exception_code != EXCEPTION_BREAKPOINT);
29312924
2932- #if defined(USE_VECTORED_EXCEPTION_HANDLING)
2933- LONG WINAPI topLevelVectoredExceptionFilter (struct _EXCEPTION_POINTERS * exceptionInfo) {
2934- PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord ;
29352925#if defined(_M_ARM64)
2936- address pc = (address) exceptionInfo->ContextRecord ->Pc ;
2937- #elif defined(_M_AMD64)
2938- address pc = (address) exceptionInfo->ContextRecord ->Rip ;
2939- #else
2940- address pc = (address) exceptionInfo->ContextRecord ->Eip ;
2926+ should_report_error = should_report_error &&
2927+ FAILED (exception_code) &&
2928+ (exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION);
29412929#endif
29422930
2943- // Fast path for code part of the code cache
2944- if (CodeCache::low_bound () <= pc && pc < CodeCache::high_bound ()) {
2945- return topLevelExceptionFilter (exceptionInfo);
2946- }
2947-
2948- // If the exception occurred in the codeCache, pass control
2949- // to our normal exception handler.
2950- CodeBlob* cb = CodeCache::find_blob (pc);
2951- if (cb != nullptr ) {
2952- return topLevelExceptionFilter (exceptionInfo);
2931+ if (should_report_error) {
2932+ report_error (t, exception_code, pc, exception_record,
2933+ exceptionInfo->ContextRecord );
29532934 }
29542935
29552936 return EXCEPTION_CONTINUE_SEARCH;
29562937}
2957- #endif
29582938
29592939#if defined(USE_VECTORED_EXCEPTION_HANDLING)
29602940LONG WINAPI topLevelUnhandledExceptionFilter (struct _EXCEPTION_POINTERS * exceptionInfo) {
@@ -4681,7 +4661,7 @@ jint os::init_2(void) {
46814661 // Setup Windows Exceptions
46824662
46834663#if defined(USE_VECTORED_EXCEPTION_HANDLING)
4684- topLevelVectoredExceptionHandler = AddVectoredExceptionHandler (1 , topLevelVectoredExceptionFilter );
4664+ topLevelVectoredExceptionHandler = AddVectoredExceptionHandler (1 , topLevelExceptionFilter );
46854665 previousUnhandledExceptionFilter = SetUnhandledExceptionFilter (topLevelUnhandledExceptionFilter);
46864666#endif
46874667
@@ -6428,3 +6408,110 @@ void os::print_user_info(outputStream* st) {
64286408void os::print_active_locale (outputStream* st) {
64296409 // not implemented yet
64306410}
6411+
6412+ /*
6413+ TODO: Investigate whether Windows AArch64 uses stack frames the way Java expects.
6414+ If so, we can replace the os::win32::platform_print_native_stack() implementation
6415+ with one that uses the mechanism in vmError.cpp (and whether this comment is still
6416+ accurate about that being the correct way to print native stacks). Otherwise, we
6417+ need to keep this implementation and document that Windows AArch64 is similar
6418+ to Windows x64 where there is commentary about Windows x64 behavior.
6419+ */
6420+ /*
6421+ * Windows/x64 does not use stack frames the way expected by Java:
6422+ * [1] in most cases, there is no frame pointer. All locals are addressed via RSP
6423+ * [2] in rare cases, when alloca() is used, a frame pointer is used, but this may
6424+ * not be RBP.
6425+ * See http://msdn.microsoft.com/en-us/library/ew5tede7.aspx
6426+ *
6427+ * So it's not possible to print the native stack using the
6428+ * while (...) {... fr = os::get_sender_for_C_frame(&fr); }
6429+ * loop in vmError.cpp. We need to roll our own loop.
6430+ */
6431+ bool os::win32::platform_print_native_stack (outputStream* st, const void * context,
6432+ char *buf, int buf_size, address& lastpc)
6433+ {
6434+ CONTEXT ctx;
6435+ if (context != nullptr ) {
6436+ memcpy (&ctx, context, sizeof (ctx));
6437+ } else {
6438+ RtlCaptureContext (&ctx);
6439+ }
6440+
6441+ st->print_cr (" Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)" );
6442+
6443+ DWORD machine_type;
6444+ STACKFRAME stk;
6445+ memset (&stk, 0 , sizeof (stk));
6446+ stk.AddrStack .Mode = AddrModeFlat;
6447+ stk.AddrFrame .Mode = AddrModeFlat;
6448+ stk.AddrPC .Mode = AddrModeFlat;
6449+
6450+ #if defined(_M_AMD64)
6451+ stk.AddrStack .Offset = ctx.Rsp ;
6452+ stk.AddrFrame .Offset = ctx.Rbp ;
6453+ stk.AddrPC .Offset = ctx.Rip ;
6454+ machine_type = IMAGE_FILE_MACHINE_AMD64;
6455+ #elif defined(_M_ARM64)
6456+ stk.AddrStack .Offset = ctx.Sp ;
6457+ stk.AddrFrame .Offset = ctx.Fp ;
6458+ stk.AddrPC .Offset = ctx.Pc ;
6459+ machine_type = IMAGE_FILE_MACHINE_ARM64;
6460+ #else
6461+ #error unknown architecture
6462+ #endif
6463+
6464+ int count = 0 ;
6465+ address lastpc_internal = 0 ;
6466+ while (count++ < StackPrintLimit) {
6467+ intptr_t * sp = (intptr_t *)stk.AddrStack .Offset ;
6468+ intptr_t * fp = (intptr_t *)stk.AddrFrame .Offset ; // NOT necessarily the same as ctx.Rbp!
6469+ address pc = (address)stk.AddrPC .Offset ;
6470+
6471+ if (pc != nullptr ) {
6472+ if (count == 2 && lastpc_internal == pc) {
6473+ // Skip it -- StackWalk64() may return the same PC
6474+ // (but different SP) on the first try.
6475+ } else {
6476+ // Don't try to create a frame(sp, fp, pc) -- on WinX64, stk.AddrFrame
6477+ // may not contain what Java expects, and may cause the frame() constructor
6478+ // to crash. Let's just print out the symbolic address.
6479+ frame::print_C_frame (st, buf, buf_size, pc);
6480+ // print source file and line, if available
6481+ char buf[128 ];
6482+ int line_no;
6483+ if (SymbolEngine::get_source_info (pc, buf, sizeof (buf), &line_no)) {
6484+ st->print (" (%s:%d)" , buf, line_no);
6485+ } else {
6486+ st->print (" (no source info available)" );
6487+ }
6488+ st->cr ();
6489+ }
6490+ lastpc_internal = pc;
6491+ }
6492+
6493+ PVOID p = WindowsDbgHelp::symFunctionTableAccess64 (GetCurrentProcess (), stk.AddrPC .Offset );
6494+ if (!p) {
6495+ // StackWalk64() can't handle this PC. Calling StackWalk64 again may cause crash.
6496+ lastpc = lastpc_internal;
6497+ break ;
6498+ }
6499+
6500+ BOOL result = WindowsDbgHelp::stackWalk64 (
6501+ machine_type, // __in DWORD MachineType,
6502+ GetCurrentProcess (), // __in HANDLE hProcess,
6503+ GetCurrentThread (), // __in HANDLE hThread,
6504+ &stk, // __inout LP STACKFRAME64 StackFrame,
6505+ &ctx); // __inout PVOID ContextRecord,
6506+
6507+ if (!result) {
6508+ break ;
6509+ }
6510+ }
6511+ if (count > StackPrintLimit) {
6512+ st->print_cr (" ...<more frames>..." );
6513+ }
6514+ st->cr ();
6515+
6516+ return true ;
6517+ }
0 commit comments