summaryrefslogtreecommitdiff
path: root/src/pal/src/exception
diff options
context:
space:
mode:
authorKonstantin Baladurin <k.baladurin@partner.samsung.com>2018-02-15 04:25:32 +0300
committerJan Vorlicek <janvorli@microsoft.com>2018-02-15 02:25:32 +0100
commit24b4aff35c51938f01fcb740777af510f50074d0 (patch)
treed3c3eabf34f3cee6871bde9aef238815b80e3cb5 /src/pal/src/exception
parent13abf204311e8c512603b5f9abb97113ad671bc1 (diff)
downloadcoreclr-24b4aff35c51938f01fcb740777af510f50074d0.tar.gz
coreclr-24b4aff35c51938f01fcb740777af510f50074d0.tar.bz2
coreclr-24b4aff35c51938f01fcb740777af510f50074d0.zip
sigsegv_handler: handle case when it is called on original stack (#16276)
* CatchHardwareExceptionHolder: use GetCurrentPalThread instead of InternalGetCurrentThread in IsEnabled method. InternalGetCurrentThread tries to create pal thread if it doesn't exist for the current thread. It's unnecessary because in this case there are no hardware exception handlers for such thread. Also CatchHardwareExceptionHolder::IsEnable is called from signal handlers and during pal thread creation non-async-signal-safe function are called. * vm/threads: change tls model for gCurrentThreadInfo variable We should use initial-exec tls model to avoid memory allocations during first access to this variable because it may ocuur in signal handlers. * sigsegv_handler: handle case when it is called on original stack If sigsegv_handler is called on original stack (for example, if segmentation fault occurs in native application's thread that hasn't alternate signal stack) we should call common_signal_handler directly othersize sigsegv_handler's stackframe will be corrupted.
Diffstat (limited to 'src/pal/src/exception')
-rw-r--r--src/pal/src/exception/seh.cpp4
-rw-r--r--src/pal/src/exception/signal.cpp38
2 files changed, 28 insertions, 14 deletions
diff --git a/src/pal/src/exception/seh.cpp b/src/pal/src/exception/seh.cpp
index 9f5f074f18..73d8ce505b 100644
--- a/src/pal/src/exception/seh.cpp
+++ b/src/pal/src/exception/seh.cpp
@@ -344,8 +344,8 @@ CatchHardwareExceptionHolder::~CatchHardwareExceptionHolder()
bool CatchHardwareExceptionHolder::IsEnabled()
{
- CPalThread *pThread = InternalGetCurrentThread();
- return pThread->IsHardwareExceptionsEnabled();
+ CPalThread *pThread = GetCurrentPalThread();
+ return pThread ? pThread->IsHardwareExceptionsEnabled() : false;
}
/*++
diff --git a/src/pal/src/exception/signal.cpp b/src/pal/src/exception/signal.cpp
index a27382315c..96dca50706 100644
--- a/src/pal/src/exception/signal.cpp
+++ b/src/pal/src/exception/signal.cpp
@@ -477,23 +477,37 @@ static void sigsegv_handler(int code, siginfo_t *siginfo, void *context)
// Establish a return point in case the common_signal_handler returns
- volatile bool contextInitialization = true;
+ if (GetCurrentPalThread())
+ {
+ volatile bool contextInitialization = true;
- SignalHandlerWorkerReturnPoint returnPoint;
- RtlCaptureContext(&returnPoint.context);
+ void *ptr = alloca(sizeof(SignalHandlerWorkerReturnPoint) + alignof(SignalHandlerWorkerReturnPoint) - 1);
+ SignalHandlerWorkerReturnPoint *pReturnPoint = (SignalHandlerWorkerReturnPoint *)ALIGN_UP(ptr, alignof(SignalHandlerWorkerReturnPoint));
+ RtlCaptureContext(&pReturnPoint->context);
- // When the signal handler worker completes, it uses setcontext to return to this point
+ // When the signal handler worker completes, it uses setcontext to return to this point
- if (contextInitialization)
- {
- contextInitialization = false;
- ExecuteHandlerOnOriginalStack(code, siginfo, context, &returnPoint);
- _ASSERTE(FALSE); // The ExecuteHandlerOnOriginalStack should never return
+ if (contextInitialization)
+ {
+ contextInitialization = false;
+ ExecuteHandlerOnOriginalStack(code, siginfo, context, pReturnPoint);
+ _ASSERTE(FALSE); // The ExecuteHandlerOnOriginalStack should never return
+ }
+
+ if (pReturnPoint->returnFromHandler)
+ {
+ return;
+ }
}
-
- if (returnPoint.returnFromHandler)
+ else
{
- return;
+ // If thread isn't created by coreclr and has alternate signal stack GetCurrentPalThread() will return NULL too.
+ // But since in this case we don't handle hardware exceptions (IsSafeToHandleHardwareException returns false)
+ // we can call common_signal_handler on the alternate stack.
+ if (common_signal_handler(code, siginfo, context, 2, (size_t)0, (size_t)siginfo->si_addr))
+ {
+ return;
+ }
}
}