-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Fix exception propagation over HW exception frame on macOS arm64 #63596
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
16652fa
f15b34e
cc2df9c
62f2e7e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -496,7 +496,9 @@ void GetContextPointers(unw_cursor_t *cursor, unw_context_t *unwContext, KNONVOL | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @janvorli, should this: runtime/src/coreclr/pal/src/exception/seh-unwind.cpp Lines 186 to 187 in f3e4e76
fpsimd_context* fp = GetNativeSigSimdContext(unwContext);
#define ASSIGN_FP_REG(reg) if (fp) *(NEON128*) &fp->vregs[reg] = winContext->V[reg]; (only pass one argument to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @am11 Seems to be the case considering the only use of runtime/src/coreclr/pal/src/exception/seh-unwind.cpp Lines 134 to 157 in f3e4e76
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if this code was ever compiling and is dead? cl.exe on Windows and clang on Linux both fail the runtime/src/coreclr/pal/src/configure.cmake Line 1033 in f3e4e76
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @am11 you are right, it is a dead code. I've added it when fixing floating point registers unwind because we had that code path for ARM64. However, the libunwind currently doesn't use the ucontext_t as unwind context for ARM64, IIRC a comment in there says it is done that way in order to reduce size of the unwind context. So everything for ARM64 with |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#ifndef HOST_WINDOWS | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
extern int g_common_signal_handler_context_locvar_offset; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Frame pointer relative offset of a local containing a pointer to the windows style context of a location | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// where a hardware exception occured. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int g_hardware_exception_context_locvar_offset = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextPointers) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -506,19 +508,17 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DWORD64 curPc = CONTEXTGetPC(context); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#ifndef __APPLE__ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Check if the PC is the return address from the SEHProcessException in the common_signal_handler. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// If that's the case, extract its local variable containing the windows style context of the hardware | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Check if the PC is the return address from the SEHProcessException. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// If that's the case, extract its local variable containing a pointer to the windows style context of the hardware | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// exception and return that. This skips the hardware signal handler trampoline that the libunwind | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// cannot cross on some systems. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// cannot cross on some systems. On macOS, it skips a similar trampoline we create in HijackFaultingThread. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if ((void*)curPc == g_SEHProcessExceptionReturnAddress) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CONTEXT* signalContext = (CONTEXT*)(CONTEXTGetFP(context) + g_common_signal_handler_context_locvar_offset); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
memcpy_s(context, sizeof(CONTEXT), signalContext, sizeof(CONTEXT)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CONTEXT* exceptionContext = *(CONTEXT**)(CONTEXTGetFP(context) + g_hardware_exception_context_locvar_offset); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
memcpy_s(context, sizeof(CONTEXT), exceptionContext, sizeof(CONTEXT)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return TRUE; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if ((context->ContextFlags & CONTEXT_EXCEPTION_ACTIVE) != 0) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System; | ||
|
||
public class Program | ||
{ | ||
private interface IFoo | ||
{ | ||
bool IsValid { get; } | ||
} | ||
|
||
private class Foo : IFoo | ||
{ | ||
public bool IsValid { get; set; } | ||
} | ||
|
||
public static int Main(string[] args) | ||
{ | ||
bool warmup = new Foo().IsValid; | ||
CatchIgnore(() => | ||
CatchRethrow(() => | ||
{ | ||
IFoo[] foos = {new Foo(), null}; | ||
foreach (var foo in foos) | ||
{ | ||
bool check = foo.IsValid; | ||
} | ||
})); | ||
|
||
return 100; | ||
} | ||
|
||
public static void CatchRethrow(Action action) | ||
{ | ||
try | ||
{ | ||
action.Invoke(); | ||
} | ||
catch (Exception e) | ||
{ | ||
Console.Out.WriteLine("catch"); | ||
Console.Out.Flush(); | ||
throw new Exception("catch", e); | ||
} | ||
} | ||
|
||
public static void CatchIgnore(Action action) | ||
{ | ||
try | ||
{ | ||
action.Invoke(); | ||
} | ||
catch (Exception) | ||
{ | ||
Console.Out.WriteLine("ignore"); | ||
Console.Out.Flush(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<CLRTestPriority>1</CLRTestPriority> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="test62058.cs" /> | ||
</ItemGroup> | ||
</Project> |
Uh oh!
There was an error while loading. Please reload this page.