summaryrefslogtreecommitdiff
path: root/src/pal
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2017-06-17 14:13:39 +0200
committerGitHub <noreply@github.com>2017-06-17 14:13:39 +0200
commita02634eb41284dbd432ef84aa38f526f955e5f64 (patch)
tree3b688a97e457dc7ee3bc9f507d9a6c8f693384d6 /src/pal
parenta6ed71c6472c8ea0f680507ae34f56aeaf6bb3d2 (diff)
downloadcoreclr-a02634eb41284dbd432ef84aa38f526f955e5f64.tar.gz
coreclr-a02634eb41284dbd432ef84aa38f526f955e5f64.tar.bz2
coreclr-a02634eb41284dbd432ef84aa38f526f955e5f64.zip
Fix chained hardware exception handling on Unix (#12344)
There is an issue when hardware exception occurs while handling another hardware exception. In such case, the exception unwinding ends up in an infinite loop. It is caused by the kernel reusing the same location for signal handler context. The fix is to use a windows style context local variable in the common_signal_handler that contains the right context - it is the original signal context converted to windows style context.
Diffstat (limited to 'src/pal')
-rw-r--r--src/pal/src/exception/seh-unwind.cpp4
-rw-r--r--src/pal/src/exception/signal.cpp6
2 files changed, 7 insertions, 3 deletions
diff --git a/src/pal/src/exception/seh-unwind.cpp b/src/pal/src/exception/seh-unwind.cpp
index 360ea3e987..f1f25b01e8 100644
--- a/src/pal/src/exception/seh-unwind.cpp
+++ b/src/pal/src/exception/seh-unwind.cpp
@@ -266,8 +266,8 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP
// cannot cross on some systems.
if ((void*)curPc == g_SEHProcessExceptionReturnAddress)
{
- CONTEXT* nativeContext = *(CONTEXT**)(CONTEXTGetFP(context) + g_common_signal_handler_context_locvar_offset);
- memcpy_s(context, sizeof(CONTEXT), nativeContext, sizeof(CONTEXT));
+ CONTEXT* signalContext = (CONTEXT*)(CONTEXTGetFP(context) + g_common_signal_handler_context_locvar_offset);
+ memcpy_s(context, sizeof(CONTEXT), signalContext, sizeof(CONTEXT));
return TRUE;
}
diff --git a/src/pal/src/exception/signal.cpp b/src/pal/src/exception/signal.cpp
index 6a046bd00b..b580ba4f51 100644
--- a/src/pal/src/exception/signal.cpp
+++ b/src/pal/src/exception/signal.cpp
@@ -761,12 +761,13 @@ __attribute__((noinline))
static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext, int numParams, ...)
{
sigset_t signal_set;
+ CONTEXT signalContextRecord;
CONTEXT *contextRecord;
EXCEPTION_RECORD *exceptionRecord;
native_context_t *ucontext;
ucontext = (native_context_t *)sigcontext;
- g_common_signal_handler_context_locvar_offset = (int)((char*)&contextRecord - (char*)__builtin_frame_address(0));
+ g_common_signal_handler_context_locvar_offset = (int)((char*)&signalContextRecord - (char*)__builtin_frame_address(0));
AllocateExceptionRecords(&exceptionRecord, &contextRecord);
@@ -809,6 +810,9 @@ static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext
}
contextRecord->ContextFlags |= CONTEXT_EXCEPTION_ACTIVE;
+
+ memcpy_s(&signalContextRecord, sizeof(CONTEXT), contextRecord, sizeof(CONTEXT));
+
// The exception object takes ownership of the exceptionRecord and contextRecord
PAL_SEHException exception(exceptionRecord, contextRecord);