summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/exceptions.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/exceptions.cc')
-rw-r--r--winsup/cygwin/exceptions.cc14
1 files changed, 10 insertions, 4 deletions
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 27b571ee1..112d79206 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -232,7 +232,7 @@ class stack_info
#ifdef __x86_64__
CONTEXT c;
UNWIND_HISTORY_TABLE hist;
- __stack_t *sigstackptr;
+ __tlsstack_t *sigstackptr;
#endif
public:
STACKFRAME sf; /* For storing the stack information */
@@ -696,11 +696,17 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
}
break;
+ case STATUS_STACK_OVERFLOW:
+ /* If we encounter a stack overflow, and if the thread has no alternate
+ stack, don't even try to call a signal handler. This is in line with
+ Linux behaviour and also makes a lot of sense on Windows. */
+ if (me.altstack.ss_flags)
+ global_sigs[SIGSEGV].sa_handler = SIG_DFL;
+ /*FALLTHRU*/
case STATUS_ARRAY_BOUNDS_EXCEEDED:
case STATUS_IN_PAGE_ERROR:
case STATUS_NO_MEMORY:
case STATUS_INVALID_DISPOSITION:
- case STATUS_STACK_OVERFLOW:
si.si_signo = SIGSEGV;
si.si_code = SEGV_MAPERR;
break;
@@ -894,7 +900,7 @@ _cygtls::interrupt_now (CONTEXT *cx, siginfo_t& si, void *handler,
void __reg3
_cygtls::interrupt_setup (siginfo_t& si, void *handler, struct sigaction& siga)
{
- push ((__stack_t) sigdelayed);
+ push ((__tlsstack_t) sigdelayed);
deltamask = siga.sa_mask & ~SIG_NONMASKABLE;
sa_flags = siga.sa_flags;
func = (void (*) (int, siginfo_t *, void *)) handler;
@@ -1497,7 +1503,7 @@ _cygtls::call_signal_handler ()
/* Pop the stack if the next "return address" is sigdelayed, since
this function is doing what sigdelayed would have done anyway. */
- if (retaddr () == (__stack_t) sigdelayed)
+ if (retaddr () == (__tlsstack_t) sigdelayed)
pop ();
debug_only_printf ("dealing with signal %d", sig);