diff options
author | Konstantin Baladurin <k.baladurin@partner.samsung.com> | 2018-02-15 04:25:32 +0300 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2018-02-15 02:25:32 +0100 |
commit | 24b4aff35c51938f01fcb740777af510f50074d0 (patch) | |
tree | d3c3eabf34f3cee6871bde9aef238815b80e3cb5 /src/pal/src/exception | |
parent | 13abf204311e8c512603b5f9abb97113ad671bc1 (diff) | |
download | coreclr-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.cpp | 4 | ||||
-rw-r--r-- | src/pal/src/exception/signal.cpp | 38 |
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; + } } } |