make-alpha
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Handling fatal signals in GNU make


From: Paul Smith
Subject: Re: Handling fatal signals in GNU make
Date: Sun, 09 Jun 2019 15:55:31 -0400
User-agent: Evolution 3.32.1-2

On Mon, 2019-05-20 at 21:20 -0700, Paul Eggert wrote:
> Paul Smith wrote:
> > Another thought I had: we have already wrapped most system calls with
> > the EINTRLOOP macro.  One possibility would be to extend this macro so
> > it does the check of the "received fatal signal" flag, then disable
> > SA_RESTART and rely on this loop in all situations.  We might need to
> > review the code to make sure we haven't missed places that need it.
> > This is seriously old-school: I guess this is how signals had to be
> > managed originally?
> 
> This sounds pretty much like what Emacs does when it's run interactively. 
> Yes, 
> it's old-school, but it does work. As I recall, Emacs used SA_RESTART long 
> ago, 
> but that was flaky and eventually was backed out in favor of the old-school 
> approach.

I can see how this can work with the jobserver pipes: we already
disable SA_RESTART there so that we can be interrupted when reading the
pipe and we have our dup'd pipe fd trick which works.  Or, if available
we use pselect().

But, in this situation how do we handle wait() where we're waiting for
children?  Suppose this happens:

 1) make checks for fatal signals and finds none
 2) SIGTERM is received
 3) make enters wait() waiting for a child to exit

Here make will hang in wait() until a child exits, which is not what we
want.

There are lots of more complicated changes we could make try to handle
this situation.  However, examining the current signal handler code I
note that the handler already waits for all its children to exit.

So, I think the right behaviour here is to modify the signal handler so
that in addition to setting a flag it will also signal all the children
(kill is signal handler-safe), then follow this process:

 a) ensure all children we have started are known
 b) check for fatal signals
 c) enter wait()

This should allow the wait() to return quickly since children will die.
Of course, if children do NOT die (e.g. they ignore the signal) make
won't exit either, but that's already how things work.

The issue here, of course, is that we need to ensure that the child
chain is managed appropriately such that it can always be accessed in
the signal handler... probably blocking signals during critical
operations or something like that.  Sigh.

Any other ideas or opinions, I'm open to it.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]