Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 24b4aff

Browse files
Konstantin Baladurinjanvorli
authored andcommitted
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.
1 parent 13abf20 commit 24b4aff

File tree

3 files changed

+29
-15
lines changed

3 files changed

+29
-15
lines changed

src/pal/src/exception/seh.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,8 @@ CatchHardwareExceptionHolder::~CatchHardwareExceptionHolder()
344344

345345
bool CatchHardwareExceptionHolder::IsEnabled()
346346
{
347-
CPalThread *pThread = InternalGetCurrentThread();
348-
return pThread->IsHardwareExceptionsEnabled();
347+
CPalThread *pThread = GetCurrentPalThread();
348+
return pThread ? pThread->IsHardwareExceptionsEnabled() : false;
349349
}
350350

351351
/*++

src/pal/src/exception/signal.cpp

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -477,23 +477,37 @@ static void sigsegv_handler(int code, siginfo_t *siginfo, void *context)
477477

478478
// Establish a return point in case the common_signal_handler returns
479479

480-
volatile bool contextInitialization = true;
480+
if (GetCurrentPalThread())
481+
{
482+
volatile bool contextInitialization = true;
481483

482-
SignalHandlerWorkerReturnPoint returnPoint;
483-
RtlCaptureContext(&returnPoint.context);
484+
void *ptr = alloca(sizeof(SignalHandlerWorkerReturnPoint) + alignof(SignalHandlerWorkerReturnPoint) - 1);
485+
SignalHandlerWorkerReturnPoint *pReturnPoint = (SignalHandlerWorkerReturnPoint *)ALIGN_UP(ptr, alignof(SignalHandlerWorkerReturnPoint));
486+
RtlCaptureContext(&pReturnPoint->context);
484487

485-
// When the signal handler worker completes, it uses setcontext to return to this point
488+
// When the signal handler worker completes, it uses setcontext to return to this point
486489

487-
if (contextInitialization)
488-
{
489-
contextInitialization = false;
490-
ExecuteHandlerOnOriginalStack(code, siginfo, context, &returnPoint);
491-
_ASSERTE(FALSE); // The ExecuteHandlerOnOriginalStack should never return
490+
if (contextInitialization)
491+
{
492+
contextInitialization = false;
493+
ExecuteHandlerOnOriginalStack(code, siginfo, context, pReturnPoint);
494+
_ASSERTE(FALSE); // The ExecuteHandlerOnOriginalStack should never return
495+
}
496+
497+
if (pReturnPoint->returnFromHandler)
498+
{
499+
return;
500+
}
492501
}
493-
494-
if (returnPoint.returnFromHandler)
502+
else
495503
{
496-
return;
504+
// If thread isn't created by coreclr and has alternate signal stack GetCurrentPalThread() will return NULL too.
505+
// But since in this case we don't handle hardware exceptions (IsSafeToHandleHardwareException returns false)
506+
// we can call common_signal_handler on the alternate stack.
507+
if (common_signal_handler(code, siginfo, context, 2, (size_t)0, (size_t)siginfo->si_addr))
508+
{
509+
return;
510+
}
497511
}
498512
}
499513

src/vm/threads.inl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#ifndef __llvm__
2727
EXTERN_C __declspec(thread) ThreadLocalInfo gCurrentThreadInfo;
2828
#else // !__llvm__
29-
EXTERN_C __thread ThreadLocalInfo gCurrentThreadInfo;
29+
EXTERN_C __thread ThreadLocalInfo gCurrentThreadInfo __attribute__ ((tls_model("initial-exec")));
3030
#endif // !__llvm__
3131

3232
EXTERN_C inline Thread* STDCALL GetThread()

0 commit comments

Comments
 (0)