[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