Handling fatal signals in GNU make
Paul Smith <[email protected]> Mon, 20 May 2019 08:57:04 -0400
| Newsgroups | gmane.comp.gnu.make.devel |
|---|---|
| Organization | GNU's Not UNIX! |
| Message-ID | <[email protected]> |
There are a number of Savannah bugs around GNU make's handling of fatal signals. There can be deadlocks, etc. The fundamental problem is that when make receives a fatal signal it will run the entire shutdown from within the signal handler. That can lead to a lot of problems. The obvious solution is to not do this and instead just set a flag or similar in the signal handler, then check this flag in the main code. Of course this is not so simple: as we well know from previous wrestling with this it's very difficult to handle both waiting and signal handling in a sane way. We managed this in more modern systems by using pselect() and in older systems with a trick of closing the jobserver pipe. On systems that support pselect() we could try to use it to create critical sections for fatal signals in addition to SIGCHLD: block fatal signals, check the "received fatal signal" flag, then use pselect() to re-enable while waiting. Of course we still need to introduce checks of the "fatal signal received" flag around the code so we can react to it even when we're doing things other than waiting for children (or jobserver tokens). And, we would need to increase the usage of pselect() to more places that we might wait; currently it's only used when we want to wait for jobserver tokens. 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? And, I haven't given too much thought so far to Windows support; I'm not sure how compatible it is with this model of signal handling. An even more adventurous option would be to change make to be multithreaded. To really solve this problem using multithreading would require a significant structural change, though.