|
Message-ID: <20190306182030.GU23599@brightrain.aerifal.cx> Date: Wed, 6 Mar 2019 13:20:30 -0500 From: Rich Felker <dalias@...c.org> To: Markus Wichmann <nullplan@....net> Cc: musl@...ts.openwall.com Subject: Re: sigaltstack for implementation-internal signals? On Wed, Mar 06, 2019 at 06:11:19PM +0100, Markus Wichmann wrote: > On Wed, Mar 06, 2019 at 11:25:08AM -0500, Rich Felker wrote: > > On Wed, Mar 06, 2019 at 05:07:40PM +0100, Markus Wichmann wrote: > > > libc uses signal handlers. And you use libc. Connect the dots... > > > > This is an implementation detail, not part of the specification. > > Well, then the spec must allow for this implementation (else it would > not be conforming). Which means we move from "libc uses signal handlers" > to "libc might use signal handlers". From a practical point of view, > that is no difference at all. The question is whether it's a conforming implementation at all. If the use of signals is visible in ways it shouldn't be (i.e. without doing hacks outside the scope of the language/API like setting a bogus stack pointer) then that's non-conforming. That (aside from other practical necessities to prevent breakage) is why we take such measures to "hide" the internal use of signals, like preventing them from being added to sigset_t. > But the point about not being able to block these signals remains... not > sure what the right thing is, really. On one hand, this breaks > applications that assume no signal will arrive after blocking signals, > on the other hand, blocking libc-internal signals might deadlock. (We > had that thread about go a while back, remember?) It doesn't break applications that assume no signal will arrive, since its arrival isn't observable within the standard interfaces. It breaks applications that are doing particular hacks outside of the scope of what's specified. > One thing I noticed: At least on Linux, the main thread must always have > a valid stack pointer in order to facilitate the rather fragile stack > expansion mechanism. As I recall, that mechanism is triggered every time > a stack pointer reference causes a page fault, and if the ulimit for the > stack size is exceeded, the process is signalled. I don't see how this matters. If you set the stack pointer to an invalid value (e.g. to use it as a general purpose register), you're not going to be trying to dereference it. > > > SIGTIMER: > > > That one is needed in timer_create() to be able to spawn a thread if > > > someone creates a timer with SIGEV_THREAD. Since the handling thread is > > > spawned immediately, the signal is taken only on the stack of the > > > internal thread. And the handler itself does nothing. > > > > This can be removed at some point anyway. SIGEV_THREAD is easier to do > > in userspace without kernel timer objects and signals. > > > > How? clock_nanosleep() in a loop, then? Yes. What we're doing now is essentially a huge pile of unnecessary complexity and kernel resource consumption to get the same effect as clock_nanosleep in a loop. However there is some convenience; it avoids having to calculate overruns ourselves and allows timer_settime, etc. to use the common kernel interface regardless of which type of timer they're acting on. This is why I haven't converted it over yet; converting it requires writing the equivalent logic for "userspace timer threads". > > > BTW, is there a > > > reason that handler is installed with SA_SIGINFO if it does nothing with > > > the extra info? > > > > if (si.si_code == SI_TIMER && !setjmp(jb)) { > > > > That is in the handling thread, and the signal info comes out of > sigwaitinfo(). No, I meant timer_handler(), which is installed with > SA_SIGINFO but does nothing. Well before it was in the handler, but it's not clear that you can use sigwaitinfo to get the info without SI_SIGINFO. See the application usage notes in POSIX for sigwaitinfo: "Note that in order to ensure that generated signals are queued and signal values passed to sigqueue() are available in si_value, applications which use sigwaitinfo() or sigtimedwait() need to set the SA_SIGINFO flag for each signal in the set (see Signal Concepts). This means setting each signal to be handled by a three-argument signal-catching function, even if the handler will never be called. It is not possible (portably) to set a signal handler to SIG_DFL while setting the SA_SIGINFO flag, because assigning to the sa_handler member of struct sigaction instead of the sa_sigaction member would result in undefined behavior, and SIG_DFL need not be assignment-compatible with sa_sigaction. Even if an assignment of SIG_DFL to sa_sigaction is accepted by the compiler, the implementation need not treat this value as special-it could just be taken as the address of a signal-catching function." Thus the SA_SIGINFO flag was kept with the understanding that it might be required for the current logic to work. Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.