On Wed, Jun 12, 2024 at 10:14:01AM +0530, Dev Jain wrote:
On 6/11/24 16:55, Mark Brown wrote:The point is that the delivery and blocking are done prior to the
On Tue, Jun 11, 2024 at 01:26:50PM +0530, Dev Jain wrote:Isn't "signal being masked" equivalent to what I wrote...
+ * A signal is said to be delivered, when the program takes action on theI'm not sure that's what my understanding of a blocked signal is, I
+ * signal: such action may involve termination of the process, ignoring the
+ * signal, terminating with core dump, stopping the process, or continuing the
+ * process if it was currently stopped. A signal is said to be blocked when the
+ * program refuses to take any of the above actions; note that, this is not the
+ * same as ignoring the signal. At a later time, the program may unblock the
+ * signal and then it will have to take one of the five actions
+ * described above.
would interpret "blocked" as a signal being masked (this usage can be
seen in for example sigaction(2)). I'd also interpret delivery of the
signal as happening when the signal handler is invoked rather than
something that the handler has control over (the comment later on says
that so I think it's just an issue here). Perhaps I'm confused about
terminology though, this is just usage I've picked up and ICBW.
man signal(7): Under "Signal mask and pending signals":-
"A signal may be blocked, which means that it will not be delivered
until it is later unblocked."
Under "Signal dispositions":-
"Each signal has a current disposition, which determines how the
process behaves when it is delivered the signal."
process getting involved in the handling of the signal, the delivery
happens when the signal handler is invoked. The program requests
delivery or blocking but it doesn't actually do the delivery or blocking
itself.
"The comment later on says that", which comment and what does it say,That signals are blocked before the process sees them.
sorry didn't get you.
TBH I'm not sure what you mean there by real time signals, I can't seeYes, thanks for the note, but do need to include it in the+ * For standard signals (also see real-time signals in the man page), multipleSee also SA_NODEFER.
+ * blocked instances of the same signal are not queued; such a signal will
+ * be delivered just once.
comments? This is a specific setting...
a reference to real time in the copies of signal(2), signal(7) or
sigaction(2) on my system. I suspect SA_NODEFER is the actual thing
here.
I still don't follow what the above means. When you say "invariant" youThis is the point I raised in the cover letter and in this program: the mask+ /* SEGV has been blocked in sa_mask, but ucontext is invariant */We're not manipulating the masks outside of main() so it's a bit unclear
+ ret = sigismember(&(((ucontext_t *)uc)->uc_sigmask), SIGSEGV);
+ ksft_test_result(ret == 0, "SEGV not blocked in ucontext\n");
what the mention of ucontext being invariant is all about here?
stores the set of blocked signals. What should happen when I block signals
using sigaction()? According to the man pages, one could easily come to
an erroneous conclusion that these signals will also be present as blocked
in ucontext. I am making a point that, SEGV and USR1 have been blocked,
but they have not been added into ucontext, i.e ucontext is invariant w.r.t
to before and in the handler.
don't specify with respect to what, and it's not clear to me why the
saved context in ucontext would have changed without the handler writing
to it. For clarity I think this needs to say what the ucontext is
expected to be the same as/different to.
The general flow with signals is that the context at the time the signal
is delivered is saved to the context structure, then the signal handler
context is set up and the signal handler invoked. There are a number of
ways in which the signal handler context may differ from the context
that was interrupted, additional signals being masked is one of those.
On return from the signal handler the context is then restored from
memory and we restart from that context, potentially including
modifications made during handling. This means that the state in the
signal handler may be different to the state in the context that was
preempted by it.
Like I say I think this needs a comment, it's not obvious from theBefore raise(SIGUSR1), we register a handler for it: handler_verify_ucontext.+ act.sa_sigaction = &handler_verify_ucontext;But we just raised SIGUSR1 rather than SIGUSR2? If nothing else this
+ if (sigaction(SIGUSR1, &act, NULL))
+ ksft_exit_fail_perror("Cannot install handler");
+
+ if (raise(SIGUSR1))
+ ksft_exit_fail_perror("raise");
+
+ ksft_print_msg("USR2 still blocked on return from handler\n");
bit is a little unclear.
So, we jump there, we verify that USR2 is present in ucontext (since we mangled
with ucontext before), then we raise(SIGUSR2): the program must not terminate
since USR2 is blocked in ¤t->blocked. This is described by ksft_print_msg().
immediate code what the USR1 handler is doing and we're not doing
anything in this context to verify anything about USR2 so it looks like
a missed search/replace.