Discussion:
Do uc_link and uc_stack serve any purpose in Issue 7?
Matthew Dempsky
2014-06-03 22:08:50 UTC
Permalink
Issue 6 said that ucontext_t's uc_link and uc_stack fields were used
with makecontext() to configure where a context would return to and
where its stack should be located. Issue 7 though removed
makecontext() (along with the other *context() functions), but kept
the uc_link and uc_stack fields. Is there any point to keeping them?
Could ucontext's mandated fields be trimmed down to just uc_mcontext
and uc_sigmask?

It seems like the only portable thing an Issue 7 application could do
with uc_link and uc_stack is store values in them and read them back,
and ucontext_t seems like a suboptimal type for storing ucontext_t*
and stack_t values.

I took a look at least how Linux and NetBSD use uc_link and uc_stack
in getcontext() and for signal handlers set with SA_SIGINFO.

On Linux (Ubuntu 14.04), getcontext() doesn't seem to touch uc_link or
uc_stack at all, and SA_SIGINFO signal handler's ctx gets a NULL
uc_link and a uc_stack set to information about the *alternate* stack
(i.e., as returned by sigaltstack(); so uc_stack.ss_flags & SS_ONSTACK
is set according to whether the interrupted context was running on the
alternate stack or not).

On NetBSD (looking at CVS source), each thread in the kernel has a
"ctxlink" field that's used to persist the uc_link; so when you call
setcontext() it saves the uc_link pointer, and then getcontext() just
repopulates uc_link with this pointer. (I.e., from the kernel's point
of view, it seems to be just an extra word of opaque per-thread state
that needs to be persisted.) Also, getcontext() populates uc_stack
with the thread's alternate stack when running there, otherwise it
returns the *initial thread*'s main stack. For SA_SIGINFO, uc_stack is
just memset to all zero bytes.
Rich Felker
2014-06-04 04:35:19 UTC
Permalink
Post by Matthew Dempsky
Issue 6 said that ucontext_t's uc_link and uc_stack fields were used
with makecontext() to configure where a context would return to and
where its stack should be located. Issue 7 though removed
makecontext() (along with the other *context() functions), but kept
the uc_link and uc_stack fields. Is there any point to keeping them?
Could ucontext's mandated fields be trimmed down to just uc_mcontext
and uc_sigmask?
[...]
On Linux (Ubuntu 14.04), getcontext() doesn't seem to touch uc_link or
uc_stack at all, and SA_SIGINFO signal handler's ctx gets a NULL
uc_link and a uc_stack set to information about the *alternate* stack
(i.e., as returned by sigaltstack(); so uc_stack.ss_flags & SS_ONSTACK
is set according to whether the interrupted context was running on the
alternate stack or not).
As you've said, at least on Linux, uc_stack can be used from a signal
handler to determine if the interrupted code was running on the
alternate signal stack, at least in practice. It's not clear to me
whether the standard intends that such usage be supported, and I don't
have any particular examples in mind where it would be useful, but I
expect they do exist.

Rich
Matthew Dempsky
2014-06-04 06:39:50 UTC
Permalink
Post by Rich Felker
As you've said, at least on Linux, uc_stack can be used from a signal
handler to determine if the interrupted code was running on the
alternate signal stack, at least in practice. It's not clear to me
whether the standard intends that such usage be supported, and I don't
have any particular examples in mind where it would be useful, but I
expect they do exist.
Fair enough, and it looks like FreeBSD sets uc_stack and uc_link the
same way as Linux (i.e., getcontext() doesn't touch them, and
SA_SIGINFO sets uc_stack like sigaltstack() would return and uc_link
to NULL).

Looking at illumos, its SA_SIGINFO handling looks similar (i.e.,
uc_stack.ss_flags & SS_ONSTACK indicates whether the interrupted
context was running on the alternate stack), except like NetBSD's
getcontext(), in the not-on-stack it fakes up a stack_t value based on
the initial thread's stack area. It also persists/restores uc_link
like NetBSD.

So I suppose maybe uc_link and uc_stack do still have some portable
use with Issue 7, at least assuming illumos behavior (which seems to
best fit POSIX's descriptions). You can walk up the stack of
interrupted contexts, and see whether they're on the alternate stack
and what their signal masks were. But like you say, I can't think how
that might actually be useful off hand either.

Continue reading on narkive:
Loading...