Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2015-04-02 20:15:07 +0300
committerJon TURNEY <jon.turney@dronecode.org.uk>2015-04-10 17:34:42 +0300
commit0a0565d88173668e256a81a6a3dea337745d8256 (patch)
treecb8d1509fe91f6950e7c21689f8eea31308911ba /winsup
parenta5efc75cc195d2fa801b34461978440355dd9631 (diff)
Only construct ucontext for SA_SIGINFO signal handlers
* exceptions.cc (call_signal_handler): Only bother to construct the ucontext for signal handlers with SA_SIGINFO set. Set mcontext.oldmask. Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog6
-rw-r--r--winsup/cygwin/exceptions.cc54
2 files changed, 38 insertions, 22 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 6a8b8f5f0..ec70f1a1f 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,9 @@
+2015-04-02 Jon TURNEY <jon.turney@dronecode.org.uk>
+
+ * exceptions.cc (call_signal_handler): Only bother to construct
+ the ucontext for signal handlers with SA_SIGINFO set. Set
+ mcontext.oldmask.
+
2015-04-04 Jon TURNEY <jon.turney@dronecode.org.uk>
* exceptions.cc (call_signal_handler): Zero initialize context and set
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index fe543aee4..0c9ee1459 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -1485,42 +1485,52 @@ _cygtls::call_signal_handler ()
debug_only_printf ("dealing with signal %d", sig);
this_sa_flags = sa_flags;
+ sigset_t this_oldmask = set_process_mask_delta ();
+
/* Save information locally on stack to pass to handler. */
int thissig = sig;
siginfo_t thissi = infodata;
void (*thisfunc) (int, siginfo_t *, void *) = func;
- ucontext_t thiscontext;
- thiscontext.uc_link = 0;
- thiscontext.uc_flags = 0;
- if (thissi.si_cyg)
- memcpy (&thiscontext.uc_mcontext, ((cygwin_exception *)thissi.si_cyg)->context(), sizeof(CONTEXT));
- else
+ ucontext_t context;
+ ucontext_t *thiscontext = NULL;
+
+ /* Only make a context for SA_SIGINFO handlers */
+ if (this_sa_flags & SA_SIGINFO)
{
- /* FIXME: Really this should be the context which the signal interrupted? */
- memset(&thiscontext.uc_mcontext, 0, sizeof(struct __mcontext));
- thiscontext.uc_mcontext.ctxflags = CONTEXT_FULL;
- RtlCaptureContext ((CONTEXT *)&thiscontext.uc_mcontext);
- }
+ context.uc_link = 0;
+ context.uc_flags = 0;
+ if (thissi.si_cyg)
+ memcpy (&context.uc_mcontext, ((cygwin_exception *)thissi.si_cyg)->context(), sizeof(CONTEXT));
+ else
+ {
+ /* FIXME: Really this should be the context which the signal interrupted? */
+ memset(&context.uc_mcontext, 0, sizeof(struct __mcontext));
+ context.uc_mcontext.ctxflags = CONTEXT_FULL;
+ RtlCaptureContext ((CONTEXT *)&context.uc_mcontext);
+ }
- /* FIXME: If/when sigaltstack is implemented, this will need to do
- something more complicated */
- thiscontext.uc_stack.ss_sp = NtCurrentTeb ()->Tib.StackBase;
- thiscontext.uc_stack.ss_flags = 0;
- if (!NtCurrentTeb ()->DeallocationStack)
- thiscontext.uc_stack.ss_size = (uintptr_t)NtCurrentTeb ()->Tib.StackLimit - (uintptr_t)NtCurrentTeb ()->Tib.StackBase;
- else
- thiscontext.uc_stack.ss_size = (uintptr_t)NtCurrentTeb ()->DeallocationStack - (uintptr_t)NtCurrentTeb ()->Tib.StackBase;
+ /* FIXME: If/when sigaltstack is implemented, this will need to do
+ something more complicated */
+ context.uc_stack.ss_sp = NtCurrentTeb ()->Tib.StackBase;
+ context.uc_stack.ss_flags = 0;
+ if (!NtCurrentTeb ()->DeallocationStack)
+ context.uc_stack.ss_size = (uintptr_t)NtCurrentTeb ()->Tib.StackLimit - (uintptr_t)NtCurrentTeb ()->Tib.StackBase;
+ else
+ context.uc_stack.ss_size = (uintptr_t)NtCurrentTeb ()->DeallocationStack - (uintptr_t)NtCurrentTeb ()->Tib.StackBase;
+
+ context.uc_sigmask = context.uc_mcontext.oldmask = this_oldmask;
+
+ thiscontext = &context;
+ }
- sigset_t this_oldmask = set_process_mask_delta ();
- thiscontext.uc_sigmask = this_oldmask;
int this_errno = saved_errno;
reset_signal_arrived ();
incyg = false;
sig = 0; /* Flag that we can accept another signal */
unlock (); /* unlock signal stack */
- thisfunc (thissig, &thissi, &thiscontext);
+ thisfunc (thissig, &thissi, thiscontext);
incyg = true;
set_signal_mask (_my_tls.sigmask, this_oldmask);