@@ -2729,6 +2729,10 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
27292729 // Verify that OS save/restore AVX registers.
27302730 return Handle_Exception (exceptionInfo, VM_Version::cpuinfo_cont_addr ());
27312731 }
2732+ #elif defined(_M_ARM64)
2733+ if (handle_safefetch (exception_code, pc, (void *)exceptionInfo->ContextRecord )) {
2734+ return EXCEPTION_CONTINUE_EXECUTION;
2735+ }
27322736#endif
27332737
27342738 if (t != nullptr && t->is_Java_thread ()) {
@@ -2761,10 +2765,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
27612765 // Fatal red zone violation.
27622766 overflow_state->disable_stack_red_zone ();
27632767 tty->print_raw_cr (" An unrecoverable stack overflow has occurred." );
2764- #if !defined(USE_VECTORED_EXCEPTION_HANDLING)
27652768 report_error (t, exception_code, pc, exception_record,
27662769 exceptionInfo->ContextRecord );
2767- #endif
27682770 return EXCEPTION_CONTINUE_SEARCH;
27692771 }
27702772 } else if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
@@ -2820,10 +2822,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
28202822#endif
28212823
28222824 // Stack overflow or null pointer exception in native code.
2823- #if !defined(USE_VECTORED_EXCEPTION_HANDLING)
28242825 report_error (t, exception_code, pc, exception_record,
28252826 exceptionInfo->ContextRecord );
2826- #endif
28272827 return EXCEPTION_CONTINUE_SEARCH;
28282828 } // /EXCEPTION_ACCESS_VIOLATION
28292829 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -2897,41 +2897,21 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
28972897 }
28982898 }
28992899
2900- #if !defined(USE_VECTORED_EXCEPTION_HANDLING)
2901- if (exception_code != EXCEPTION_BREAKPOINT) {
2902- report_error (t, exception_code, pc, exception_record,
2903- exceptionInfo->ContextRecord );
2904- }
2905- #endif
2906- return EXCEPTION_CONTINUE_SEARCH;
2907- }
2900+ bool should_report_error = (exception_code != EXCEPTION_BREAKPOINT);
29082901
2909- #if defined(USE_VECTORED_EXCEPTION_HANDLING)
2910- LONG WINAPI topLevelVectoredExceptionFilter (struct _EXCEPTION_POINTERS * exceptionInfo) {
2911- PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord ;
29122902#if defined(_M_ARM64)
2913- address pc = (address) exceptionInfo->ContextRecord ->Pc ;
2914- #elif defined(_M_AMD64)
2915- address pc = (address) exceptionInfo->ContextRecord ->Rip ;
2916- #else
2917- address pc = (address) exceptionInfo->ContextRecord ->Eip ;
2903+ should_report_error = should_report_error &&
2904+ FAILED (exception_code) &&
2905+ (exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION);
29182906#endif
29192907
2920- // Fast path for code part of the code cache
2921- if (CodeCache::low_bound () <= pc && pc < CodeCache::high_bound ()) {
2922- return topLevelExceptionFilter (exceptionInfo);
2923- }
2924-
2925- // If the exception occurred in the codeCache, pass control
2926- // to our normal exception handler.
2927- CodeBlob* cb = CodeCache::find_blob (pc);
2928- if (cb != nullptr ) {
2929- return topLevelExceptionFilter (exceptionInfo);
2908+ if (should_report_error) {
2909+ report_error (t, exception_code, pc, exception_record,
2910+ exceptionInfo->ContextRecord );
29302911 }
29312912
29322913 return EXCEPTION_CONTINUE_SEARCH;
29332914}
2934- #endif
29352915
29362916#if defined(USE_VECTORED_EXCEPTION_HANDLING)
29372917LONG WINAPI topLevelUnhandledExceptionFilter (struct _EXCEPTION_POINTERS * exceptionInfo) {
@@ -4657,7 +4637,7 @@ jint os::init_2(void) {
46574637 // Setup Windows Exceptions
46584638
46594639#if defined(USE_VECTORED_EXCEPTION_HANDLING)
4660- topLevelVectoredExceptionHandler = AddVectoredExceptionHandler (1 , topLevelVectoredExceptionFilter );
4640+ topLevelVectoredExceptionHandler = AddVectoredExceptionHandler (1 , topLevelExceptionFilter );
46614641 previousUnhandledExceptionFilter = SetUnhandledExceptionFilter (topLevelUnhandledExceptionFilter);
46624642#endif
46634643
@@ -6396,3 +6376,110 @@ void os::print_user_info(outputStream* st) {
63966376void os::print_active_locale (outputStream* st) {
63976377 // not implemented yet
63986378}
6379+
6380+ /*
6381+ TODO: Investigate whether Windows AArch64 uses stack frames the way Java expects.
6382+ If so, we can replace the os::win32::platform_print_native_stack() implementation
6383+ with one that uses the mechanism in vmError.cpp (and whether this comment is still
6384+ accurate about that being the correct way to print native stacks). Otherwise, we
6385+ need to keep this implementation and document that Windows AArch64 is similar
6386+ to Windows x64 where there is commentary about Windows x64 behavior.
6387+ */
6388+ /*
6389+ * Windows/x64 does not use stack frames the way expected by Java:
6390+ * [1] in most cases, there is no frame pointer. All locals are addressed via RSP
6391+ * [2] in rare cases, when alloca() is used, a frame pointer is used, but this may
6392+ * not be RBP.
6393+ * See http://msdn.microsoft.com/en-us/library/ew5tede7.aspx
6394+ *
6395+ * So it's not possible to print the native stack using the
6396+ * while (...) {... fr = os::get_sender_for_C_frame(&fr); }
6397+ * loop in vmError.cpp. We need to roll our own loop.
6398+ */
6399+ bool os::win32::platform_print_native_stack (outputStream* st, const void * context,
6400+ char *buf, int buf_size, address& lastpc)
6401+ {
6402+ CONTEXT ctx;
6403+ if (context != nullptr ) {
6404+ memcpy (&ctx, context, sizeof (ctx));
6405+ } else {
6406+ RtlCaptureContext (&ctx);
6407+ }
6408+
6409+ st->print_cr (" Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)" );
6410+
6411+ DWORD machine_type;
6412+ STACKFRAME stk;
6413+ memset (&stk, 0 , sizeof (stk));
6414+ stk.AddrStack .Mode = AddrModeFlat;
6415+ stk.AddrFrame .Mode = AddrModeFlat;
6416+ stk.AddrPC .Mode = AddrModeFlat;
6417+
6418+ #if defined(_M_AMD64)
6419+ stk.AddrStack .Offset = ctx.Rsp ;
6420+ stk.AddrFrame .Offset = ctx.Rbp ;
6421+ stk.AddrPC .Offset = ctx.Rip ;
6422+ machine_type = IMAGE_FILE_MACHINE_AMD64;
6423+ #elif defined(_M_ARM64)
6424+ stk.AddrStack .Offset = ctx.Sp ;
6425+ stk.AddrFrame .Offset = ctx.Fp ;
6426+ stk.AddrPC .Offset = ctx.Pc ;
6427+ machine_type = IMAGE_FILE_MACHINE_ARM64;
6428+ #else
6429+ #error unknown architecture
6430+ #endif
6431+
6432+ int count = 0 ;
6433+ address lastpc_internal = 0 ;
6434+ while (count++ < StackPrintLimit) {
6435+ intptr_t * sp = (intptr_t *)stk.AddrStack .Offset ;
6436+ intptr_t * fp = (intptr_t *)stk.AddrFrame .Offset ; // NOT necessarily the same as ctx.Rbp!
6437+ address pc = (address)stk.AddrPC .Offset ;
6438+
6439+ if (pc != nullptr ) {
6440+ if (count == 2 && lastpc_internal == pc) {
6441+ // Skip it -- StackWalk64() may return the same PC
6442+ // (but different SP) on the first try.
6443+ } else {
6444+ // Don't try to create a frame(sp, fp, pc) -- on WinX64, stk.AddrFrame
6445+ // may not contain what Java expects, and may cause the frame() constructor
6446+ // to crash. Let's just print out the symbolic address.
6447+ frame::print_C_frame (st, buf, buf_size, pc);
6448+ // print source file and line, if available
6449+ char buf[128 ];
6450+ int line_no;
6451+ if (SymbolEngine::get_source_info (pc, buf, sizeof (buf), &line_no)) {
6452+ st->print (" (%s:%d)" , buf, line_no);
6453+ } else {
6454+ st->print (" (no source info available)" );
6455+ }
6456+ st->cr ();
6457+ }
6458+ lastpc_internal = pc;
6459+ }
6460+
6461+ PVOID p = WindowsDbgHelp::symFunctionTableAccess64 (GetCurrentProcess (), stk.AddrPC .Offset );
6462+ if (!p) {
6463+ // StackWalk64() can't handle this PC. Calling StackWalk64 again may cause crash.
6464+ lastpc = lastpc_internal;
6465+ break ;
6466+ }
6467+
6468+ BOOL result = WindowsDbgHelp::stackWalk64 (
6469+ machine_type, // __in DWORD MachineType,
6470+ GetCurrentProcess (), // __in HANDLE hProcess,
6471+ GetCurrentThread (), // __in HANDLE hThread,
6472+ &stk, // __inout LP STACKFRAME64 StackFrame,
6473+ &ctx); // __inout PVOID ContextRecord,
6474+
6475+ if (!result) {
6476+ break ;
6477+ }
6478+ }
6479+ if (count > StackPrintLimit) {
6480+ st->print_cr (" ...<more frames>..." );
6481+ }
6482+ st->cr ();
6483+
6484+ return true ;
6485+ }
0 commit comments