Skip to content

Commit e7a547a

Browse files
committed
Don't use alternate stack on illumos or Solaris.
When .NET translates SIGSEV to NullReferenceException, it does not return from the signal handler. Instead it resumes execution at the catch handler for the exception. This is not recommend by the manpage for sigaction(2): > It is not recommended that [the ucontext] arg be used by the handler to > restore the context from before the signal delivery. The practical effect of resuming execution without returning from a handler is that the alternate stack will not be used for subsequent signal delivery. This is in contrast to the behavior on linux, which will always use the alternate stack if the stack pointer at the time of fault does not fall on the alternate stack. Since the alternate stack is only usable for a single exception, don't bother using it for any exceptions.
1 parent 8066ca3 commit e7a547a

File tree

4 files changed

+23
-9
lines changed

4 files changed

+23
-9
lines changed

src/coreclr/pal/src/exception/signal.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,13 +190,20 @@ BOOL SEHInitializeSignals(CorUnix::CPalThread *pthrCurrent, DWORD flags)
190190
handle_signal(SIGSEGV, sigsegv_handler, &g_previous_sigsegv);
191191
#else
192192
handle_signal(SIGTRAP, sigtrap_handler, &g_previous_sigtrap);
193+
int additionalFlagsForSigSegv = 0;
194+
#ifndef __sun
195+
// On platforms that support it,
193196
// SIGSEGV handler runs on a separate stack so that we can handle stack overflow
194-
handle_signal(SIGSEGV, sigsegv_handler, &g_previous_sigsegv, SA_ONSTACK);
197+
additionalFlagsForSigSegv |= SA_ONSTACK;
198+
#endif
199+
handle_signal(SIGSEGV, sigsegv_handler, &g_previous_sigsegv, additionalFlagsForSigSegv);
195200

201+
#ifndef __sun
196202
if (!pthrCurrent->EnsureSignalAlternateStack())
197203
{
198204
return FALSE;
199205
}
206+
#endif
200207

201208
// Allocate the minimal stack necessary for handling stack overflow
202209
int stackOverflowStackSize = ALIGN_UP(sizeof(SignalHandlerWorkerReturnPoint), 16) + 7 * 4096;
@@ -336,7 +343,7 @@ Return :
336343
--*/
337344
bool IsRunningOnAlternateStack(void *context)
338345
{
339-
#if HAVE_MACH_EXCEPTIONS
346+
#if HAVE_MACH_EXCEPTIONS || defined(__sun)
340347
return false;
341348
#else
342349
bool isRunningOnAlternateStack;
@@ -644,6 +651,7 @@ static void sigsegv_handler(int code, siginfo_t *siginfo, void *context)
644651
// Now that we know the SIGSEGV didn't happen due to a stack overflow, execute the common
645652
// hardware signal handler on the original stack.
646653

654+
#ifndef __sun
647655
if (GetCurrentPalThread() && IsRunningOnAlternateStack(context))
648656
{
649657
if (SwitchStackAndExecuteHandler(code, siginfo, context, 0 /* sp */)) // sp == 0 indicates execution on the original stack
@@ -652,6 +660,7 @@ static void sigsegv_handler(int code, siginfo_t *siginfo, void *context)
652660
}
653661
}
654662
else
663+
#endif
655664
{
656665
// The code flow gets here when the signal handler is not running on an alternate stack or when it wasn't created
657666
// by coreclr. In both cases, we execute the common_signal_handler directly.

src/coreclr/pal/src/include/pal/thread.hpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,11 @@ namespace CorUnix
288288
void* m_stackBase;
289289
// Limit address of the stack of this thread
290290
void* m_stackLimit;
291+
292+
#if !HAVE_MACH_EXCEPTIONS && !defined(__sun)
291293
// Signal handler's alternate stack to help with stack overflow
292294
void* m_alternateStack;
295+
#endif
293296

294297
//
295298
// The thread entry routine (called from InternalCreateThread)
@@ -343,8 +346,10 @@ namespace CorUnix
343346
m_fStartStatus(FALSE),
344347
m_fStartStatusSet(FALSE),
345348
m_stackBase(NULL),
346-
m_stackLimit(NULL),
347-
m_alternateStack(NULL)
349+
m_stackLimit(NULL)
350+
#if !HAVE_MACH_EXCEPTIONS && !defined(__sun)
351+
,m_alternateStack(NULL)
352+
#endif
348353
{
349354
};
350355

@@ -588,7 +593,7 @@ namespace CorUnix
588593
m_pNext = pNext;
589594
};
590595

591-
#if !HAVE_MACH_EXCEPTIONS
596+
#if !HAVE_MACH_EXCEPTIONS && !defined(__sun)
592597
BOOL
593598
EnsureSignalAlternateStack(
594599
void

src/coreclr/pal/src/init/sxs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ AllocatePalThread(CPalThread **ppThread)
6464
goto exit;
6565
}
6666

67-
#if !HAVE_MACH_EXCEPTIONS
67+
#if !HAVE_MACH_EXCEPTIONS && !defined(__sun)
6868
// Ensure alternate stack for SIGSEGV handling. Our SIGSEGV handler is set to
6969
// run on an alternate stack and the stack needs to be allocated per thread.
7070
if (!pThread->EnsureSignalAlternateStack())

src/coreclr/pal/src/thread/thread.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ static void InternalEndCurrentThreadWrapper(void *arg)
157157
will lock its own critical section */
158158
LOADCallDllMain(DLL_THREAD_DETACH, NULL);
159159

160-
#if !HAVE_MACH_EXCEPTIONS
160+
#if !HAVE_MACH_EXCEPTIONS && !defined(__sun)
161161
pThread->FreeSignalAlternateStack();
162162
#endif // !HAVE_MACH_EXCEPTIONS
163163

@@ -1667,7 +1667,7 @@ CPalThread::ThreadEntry(
16671667
}
16681668
#endif // HAVE_SCHED_GETAFFINITY && HAVE_SCHED_SETAFFINITY
16691669

1670-
#if !HAVE_MACH_EXCEPTIONS
1670+
#if !HAVE_MACH_EXCEPTIONS && !defined(__sun)
16711671
if (!pThread->EnsureSignalAlternateStack())
16721672
{
16731673
ASSERT("Cannot allocate alternate stack for SIGSEGV!\n");
@@ -2390,7 +2390,7 @@ CPalThread::WaitForStartStatus(
23902390
return m_fStartStatus;
23912391
}
23922392

2393-
#if !HAVE_MACH_EXCEPTIONS
2393+
#if !HAVE_MACH_EXCEPTIONS && !defined(__sun)
23942394
/*++
23952395
Function :
23962396
EnsureSignalAlternateStack

0 commit comments

Comments
 (0)