* [PATCH] Only construct ucontext for SA_SIGINFO signal handlers
@ 2015-04-02 19:30 Jon TURNEY
2015-04-03 11:18 ` Corinna Vinschen
0 siblings, 1 reply; 6+ messages in thread
From: Jon TURNEY @ 2015-04-02 19:30 UTC (permalink / raw)
To: cygwin-patches; +Cc: Jon TURNEY
* exceptions.cc (call_signal_handler): Only bother to construct
the ucontext for signal handlers with SA_SIGINFO set.
Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
---
winsup/cygwin/ChangeLog | 5 +++++
winsup/cygwin/exceptions.cc | 46 ++++++++++++++++++++++++++-------------------
2 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 3b0e111..0ddc795 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,10 @@
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.
+
+2015-04-02 Jon TURNEY <jon.turney@dronecode.org.uk>
+
* include/cygwin/signal.h (struct __mcontext): 16-byte align.
* include/sys/ucontext.h (ucontext_t): Ditto.
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 0d1f36d..bac550c 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -1490,33 +1490,41 @@ _cygtls::call_signal_handler ()
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
- RtlCaptureContext ((CONTEXT *)&thiscontext.uc_mcontext);
- /* FIXME: Really this should be the context which the signal interrupted? */
-
- /* 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;
+ ucontext_t context;
+ ucontext_t *thiscontext = NULL;
+
+ /* Only make a context for SA_SIGINFO handlers */
+ if (this_sa_flags & SA_SIGINFO)
+ {
+ 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
+ RtlCaptureContext ((CONTEXT *)&context.uc_mcontext);
+ /* FIXME: Really this should be the context which the signal interrupted? */
+
+ /* 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;
+
+ thiscontext = &context;
+ }
sigset_t this_oldmask = set_process_mask_delta ();
- thiscontext.uc_sigmask = this_oldmask;
+ context.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);
--
2.1.4
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Only construct ucontext for SA_SIGINFO signal handlers
2015-04-02 19:30 [PATCH] Only construct ucontext for SA_SIGINFO signal handlers Jon TURNEY
@ 2015-04-03 11:18 ` Corinna Vinschen
2015-04-03 12:17 ` Corinna Vinschen
0 siblings, 1 reply; 6+ messages in thread
From: Corinna Vinschen @ 2015-04-03 11:18 UTC (permalink / raw)
To: cygwin-patches
[-- Attachment #1: Type: text/plain, Size: 2133 bytes --]
On Apr 2 20:30, Jon TURNEY wrote:
> * exceptions.cc (call_signal_handler): Only bother to construct
> the ucontext for signal handlers with SA_SIGINFO set.
Looks good, except...
> + ucontext_t context;
> + ucontext_t *thiscontext = NULL;
> +
> + /* Only make a context for SA_SIGINFO handlers */
> + if (this_sa_flags & SA_SIGINFO)
> + {
> + 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
> + RtlCaptureContext ((CONTEXT *)&context.uc_mcontext);
> + /* FIXME: Really this should be the context which the signal interrupted? */
> +
> + /* 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;
> +
> + thiscontext = &context;
> + }
> sigset_t this_oldmask = set_process_mask_delta ();
> - thiscontext.uc_sigmask = this_oldmask;
> + context.uc_sigmask = this_oldmask;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This call to set_process_mask_delta() should occur before constructing
the context, so that filling in uc_sigmask can be moved into the above
`'if' branch.
On second thought, isn't this slightly wrong anyway? Shouldn't that be
context.uc_sigmask = _my_tls.sigmask;
context.uc_mcontext.oldmask = this_oldmask;
?
Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat
[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Only construct ucontext for SA_SIGINFO signal handlers
2015-04-03 11:18 ` Corinna Vinschen
@ 2015-04-03 12:17 ` Corinna Vinschen
2015-04-03 12:51 ` Jon TURNEY
0 siblings, 1 reply; 6+ messages in thread
From: Corinna Vinschen @ 2015-04-03 12:17 UTC (permalink / raw)
To: cygwin-patches
[-- Attachment #1: Type: text/plain, Size: 2554 bytes --]
On Apr 3 13:18, Corinna Vinschen wrote:
> On Apr 2 20:30, Jon TURNEY wrote:
> > * exceptions.cc (call_signal_handler): Only bother to construct
> > the ucontext for signal handlers with SA_SIGINFO set.
>
> Looks good, except...
>
> > + ucontext_t context;
> > + ucontext_t *thiscontext = NULL;
> > +
> > + /* Only make a context for SA_SIGINFO handlers */
> > + if (this_sa_flags & SA_SIGINFO)
> > + {
> > + 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
> > + RtlCaptureContext ((CONTEXT *)&context.uc_mcontext);
> > + /* FIXME: Really this should be the context which the signal interrupted? */
> > +
> > + /* 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;
> > +
> > + thiscontext = &context;
> > + }
>
>
> > sigset_t this_oldmask = set_process_mask_delta ();
> > - thiscontext.uc_sigmask = this_oldmask;
> > + context.uc_sigmask = this_oldmask;
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> This call to set_process_mask_delta() should occur before constructing
> the context, so that filling in uc_sigmask can be moved into the above
> `'if' branch.
>
> On second thought, isn't this slightly wrong anyway? Shouldn't that be
>
> context.uc_sigmask = _my_tls.sigmask;
> context.uc_mcontext.oldmask = this_oldmask;
Oh, btw., what about cr2? Right now, with the above code, it contains
a random value. It should at least be zero'ed out. Alternatively:
context.uc_mcontext.cr2 = (thissi.si_signo == SIGSEGV
|| thissi.si_signo == SIGBUS)
? (uintptr_t) thissi.si_addr : 0;
Thanks,
Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat
[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Only construct ucontext for SA_SIGINFO signal handlers
2015-04-03 12:17 ` Corinna Vinschen
@ 2015-04-03 12:51 ` Jon TURNEY
2015-04-03 14:08 ` Corinna Vinschen
0 siblings, 1 reply; 6+ messages in thread
From: Jon TURNEY @ 2015-04-03 12:51 UTC (permalink / raw)
To: cygwin-patches
On 03/04/2015 13:17, Corinna Vinschen wrote:
> On Apr 3 13:18, Corinna Vinschen wrote:
>> On Apr 2 20:30, Jon TURNEY wrote:
>>
>>> sigset_t this_oldmask = set_process_mask_delta ();
>>> - thiscontext.uc_sigmask = this_oldmask;
>>> + context.uc_sigmask = this_oldmask;
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>
>> This call to set_process_mask_delta() should occur before constructing
>> the context, so that filling in uc_sigmask can be moved into the above
>> `'if' branch.
Ok, I will move it.
>> On second thought, isn't this slightly wrong anyway? Shouldn't that be
>>
>> context.uc_sigmask = _my_tls.sigmask;
>> context.uc_mcontext.oldmask = this_oldmask;
As I wrote elsewhere: You'll have to help me understand what the
difference in meaning between ucontext_t.uc_sigmask and
ucontext_t.uc_mcontext.oldmask is.
I don't see how the value of _my_tls.sigmask has any meaning at that
point in the code.
> Oh, btw., what about cr2? Right now, with the above code, it contains
> a random value. It should at least be zero'ed out. Alternatively:
>
> context.uc_mcontext.cr2 = (thissi.si_signo == SIGSEGV
> || thissi.si_signo == SIGBUS)
> ? (uintptr_t) thissi.si_addr : 0;
>
Sure, but can we deal with that as a separate patch?
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Only construct ucontext for SA_SIGINFO signal handlers
2015-04-03 12:51 ` Jon TURNEY
@ 2015-04-03 14:08 ` Corinna Vinschen
2015-04-04 16:07 ` Jon TURNEY
0 siblings, 1 reply; 6+ messages in thread
From: Corinna Vinschen @ 2015-04-03 14:08 UTC (permalink / raw)
To: cygwin-patches
[-- Attachment #1: Type: text/plain, Size: 2765 bytes --]
On Apr 3 13:51, Jon TURNEY wrote:
> On 03/04/2015 13:17, Corinna Vinschen wrote:
> >On Apr 3 13:18, Corinna Vinschen wrote:
> >>On Apr 2 20:30, Jon TURNEY wrote:
> >>
> >>> sigset_t this_oldmask = set_process_mask_delta ();
> >>>- thiscontext.uc_sigmask = this_oldmask;
> >>>+ context.uc_sigmask = this_oldmask;
> >> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >>
> >>This call to set_process_mask_delta() should occur before constructing
> >>the context, so that filling in uc_sigmask can be moved into the above
> >>`'if' branch.
>
> Ok, I will move it.
>
> >>On second thought, isn't this slightly wrong anyway? Shouldn't that be
> >>
> >> context.uc_sigmask = _my_tls.sigmask;
> >> context.uc_mcontext.oldmask = this_oldmask;
>
> As I wrote elsewhere: You'll have to help me understand what the difference
> in meaning between ucontext_t.uc_sigmask and ucontext_t.uc_mcontext.oldmask
> is.
>
> I don't see how the value of _my_tls.sigmask has any meaning at that point
> in the code.
Ok, I had a look into the Linux source and searched the web, and here's
the problem.
One is that sigset_t on Linux is not just a 32 or 64 bit bitmask anymore,
but an array of ulong's used as a rather big sigmask.
OTOH, mcontext_t::oldmask is only the size of "unsigned long". In fact,
as it turns out by inspecting the Linux kernel, oldmask is nothing else
than the first bits of uc_sigmask which fit into an unsigned long. And
in the net I found that oldmask is just the old representation of
sigset_t, before the Linux kernel allowed more signals than fit into
a bitmask of unsigned long size. In fact, it's only for backward compat,
but unused these days.
Given that, setting context.uc_sigmask to this_oldmask is apparently
the right thing to do. For emulating backward compat (which we don't
need, but it also doesn't hurt), we could set oldmask to the same
value:
context.uc_sigmask = context.uc_mcontext.oldmask = this_oldmask;
> >Oh, btw., what about cr2? Right now, with the above code, it contains
> >a random value. It should at least be zero'ed out. Alternatively:
> >
> > context.uc_mcontext.cr2 = (thissi.si_signo == SIGSEGV
> > || thissi.si_signo == SIGBUS)
> > ? (uintptr_t) thissi.si_addr : 0;
> >
>
> Sure, but can we deal with that as a separate patch?
Yes, but you can just apply it as well. cr2 is the address of a page
fault, so that's equivalent to the value in ExceptionInformation[1]
which, in turn, is stored in si_addr in exception::handle.
Thanks,
Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat
[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Only construct ucontext for SA_SIGINFO signal handlers
2015-04-03 14:08 ` Corinna Vinschen
@ 2015-04-04 16:07 ` Jon TURNEY
0 siblings, 0 replies; 6+ messages in thread
From: Jon TURNEY @ 2015-04-04 16:07 UTC (permalink / raw)
To: cygwin-patches
On 03/04/2015 15:08, Corinna Vinschen wrote:
> On Apr 3 13:51, Jon TURNEY wrote:
>> On 03/04/2015 13:17, Corinna Vinschen wrote:
>>> On Apr 3 13:18, Corinna Vinschen wrote:
>>>> On Apr 2 20:30, Jon TURNEY wrote:
>>>>
>>>>> sigset_t this_oldmask = set_process_mask_delta ();
>>>>> - thiscontext.uc_sigmask = this_oldmask;
>>>>> + context.uc_sigmask = this_oldmask;
>>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>>
>>>> This call to set_process_mask_delta() should occur before constructing
>>>> the context, so that filling in uc_sigmask can be moved into the above
>>>> `'if' branch.
>>
>> Ok, I will move it.
>>
>>>> On second thought, isn't this slightly wrong anyway? Shouldn't that be
>>>>
>>>> context.uc_sigmask = _my_tls.sigmask;
>>>> context.uc_mcontext.oldmask = this_oldmask;
>>
>> As I wrote elsewhere: You'll have to help me understand what the difference
>> in meaning between ucontext_t.uc_sigmask and ucontext_t.uc_mcontext.oldmask
>> is.
>>
>> I don't see how the value of _my_tls.sigmask has any meaning at that point
>> in the code.
>
> Ok, I had a look into the Linux source and searched the web, and here's
> the problem.
>
> One is that sigset_t on Linux is not just a 32 or 64 bit bitmask anymore,
> but an array of ulong's used as a rather big sigmask.
>
> OTOH, mcontext_t::oldmask is only the size of "unsigned long". In fact,
> as it turns out by inspecting the Linux kernel, oldmask is nothing else
> than the first bits of uc_sigmask which fit into an unsigned long. And
> in the net I found that oldmask is just the old representation of
> sigset_t, before the Linux kernel allowed more signals than fit into
> a bitmask of unsigned long size. In fact, it's only for backward compat,
> but unused these days.
>
> Given that, setting context.uc_sigmask to this_oldmask is apparently
> the right thing to do. For emulating backward compat (which we don't
> need, but it also doesn't hurt), we could set oldmask to the same
> value:
>
> context.uc_sigmask = context.uc_mcontext.oldmask = this_oldmask;
>
Thank you very much for researching this. I tried but wasn't able to
discover anything much.
What you suggest seems right, so I'll make an updated patch including that.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-04-04 16:07 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-02 19:30 [PATCH] Only construct ucontext for SA_SIGINFO signal handlers Jon TURNEY
2015-04-03 11:18 ` Corinna Vinschen
2015-04-03 12:17 ` Corinna Vinschen
2015-04-03 12:51 ` Jon TURNEY
2015-04-03 14:08 ` Corinna Vinschen
2015-04-04 16:07 ` Jon TURNEY
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).