[RFC] Toward Shareable POSIX Signals
Daniel Colascione
dancol@dancol.org
Fri Mar 9 20:06:00 GMT 2018
On 03/09/2018 11:30 AM, Zack Weinberg wrote:
> On Fri, Mar 9, 2018 at 11:41 AM, Rich Felker <dalias@libc.org> wrote:
>> On Fri, Mar 09, 2018 at 02:43:06AM -0800, Daniel Colascione wrote:
>>> People use signals for lots of things today. They mostly work fine.
>>> I'm proposing a mechanism to make signals *less* "scary", not
>>> *more*. Besides, it's not libc's job to make value judgments about
>>> which techniques application developers should use. At this low
>>> level, libraries should provide capabilities, not opinions.
>>
>> I think we need to weigh the benefits of making signals less
>> scary/unsafe/hideous versus the benefits of leaving them so. Yes,
>> people use signals today. Most of the uses are utterly unsafe and
>> utterly wrong. Most of them are not even justified; they're for lack
>> of knowing better or just cargo-culting from something they saw done
>> elsewhere. Do new interfaces fix existing incorrect usage and
>> discourage it in the future?
>
> This is a good question to ask.
>
> I tend to think that the basic mechanism of signals -- interrupting
> normal user-space execution and transferring control to a handler
> function -- is irretrievably flawed; not even as a design, but as a
> _concept_. This should not be a thing that ever happens to user
> space. As such, I appreciate Daniel's having taken the time to
> canvass existing use cases for signals that are poorly served, or not
> served at all, by any alternative, but I'm not a fan of any of his
> proposed solutions. I would like to work toward an end-state of
> being able to remove <signal.h> from ISO C and POSIX.
Removing signals will never happen. 30 years from now, we're going to
have SIGSEGV and SIGINT; we'll probably have them in 300 years too.
First, breaking backward compatibility for the sake of removing an ugly
concept is unjustified. Rewriting the world doesn't work.
Secondly, I don't think the "concept" of signals is flawed at all.
They're asynchronous events. They're analogous to hardware interrupts.
The reason we have systems with interrupts is that in the real world,
things go wrong, and you have to allow for responding to these
circumstances in some way. It's a fact of life and a consequence of the
structure of the universe: that's why some kind of asynchronous
exception mechanism ends up being included in *every* sufficiently
complex computing environment, even ones not POSIX-derived.
I'm not proposing that we ignore the need to also come up with
signal-free interfaces for important functionality. All things being
equal, I'd prefer not to use signals. But I don't think we'll be able to
ever actually get away from them, and since we're going to be stuck with
signals regardless, we might as well make them work better.
> [Daniel:]
>>> Also, I don't see any realistic alternatives to the wait family of
>>> APIs being proposed either. (And as I explain below, "just use glib"
>>> is completely unacceptable as a response to a fundamental defect in
>>> the design of wait*(2).)
>
> pdfork / forkfd is obviously the correct replacement for SIGCHLD, and
> it's infuriating that it still hasn't gotten traction.
I recall a discussion I read about with Linus a few years ago in which
he suggested that a process-handle FD might be some kind of attack
vector because it would let people fill the PID table. That argument
makes no sense to me: in the worst case, you could count process handles
against the process ulimit. But I don't think most people should bother
with that level of restriction.
Windows has conventional process handles and gets along fine.
>> On Fri, Mar 09, 2018 at 05:58:51PM +0100, Florian Weimer wrote:
>>> But [threads] only works for asynchronous signals. It's reasonable
>>> for an application to want to catch synchronous signals (SIGBUS
>>> when dealing with file mappings, SIGFPE for arithmetic), and there
>>> is currently no thread-safe or library-safe way at all to do that.
>>
>> Yes, as I noted each use case needs to be considered separately to
>> determine if there's some other better/more-portable/whatnot way it
>> could be done already. The above applies only to SIGCHLD.
>>
>> FWIW I'm rather skeptical of many of the usage cases for synchronous
>> signals (most are dangerous papering-over of UB for dubious
>> performance reasons; never-taken "test reg,reg;jz" takes essentially 0
>> cycles on a modern uarch) but SIGBUS makes it hard to use mmap safely
>> to begin with. So there's still a lot of material to consider here.
>
> If I remember correctly, GCJ tried to use signal handlers to generate
> NullPointerExceptions not for speed reasons, but for code-size and
> exception-precision reasons. But it was never 100% reliable and it
> might have been better to go with "test reg,reg;jz" + lean harder on
> proving pointers couldn't be null.
Android's ART runtime, Mono, Microsoft's CLR, and the JVM's HotSpot all
recover from SIGSEGV and other synchronous signals. It's a good technique.
More information about the Libc-alpha
mailing list