3 ms·
It can't be done in general. A signal handler is just a function that at runtime is connected to a signal. With some work many or most unsafe handlers in the wi
by jstimpfle 9y ago
It can't be done in general. A signal handler is just a function that at runtime is connected to a signal. With some work many or most unsafe handlers in the wild can be detected, but so can many other problems, I guess.
- verytrivial 9y agoI'll bite. A helpful compiler would at an appropriate warning level tell you when you are setting a signal handler with a function you haven't (helpfully) annotated with some construct to say "this thing is a signal handler". Said helpful compiler would then also use this helpful annotation to forbid or loudly warn against a helpful subset of naught functions it is able to deduce are being called therein because human programmers cannot be reasonably expected to consume all 64 pages of POSIX function specs before calling any one of them. Seriously.
- jstimpfle 9y agoThat's what I was saying. So why don't you step ahead and do it? I'm sure it will be not more than two weeks worth of work. And it will fatten up the compiler only a little bit. And it will annoy proficient programmers only a little bit. How would you deal with calling a function that is externally defined, so you can't easily check if it does something unsafe (or calls another function that does). I'd figure any attempt to check if a signal handler is safe would have to be either extremely expensive or pretty half-arsed. (That's what I was saying, except the bit that programmers cannot reasonably be expected to understand what to do in a signal handler. That you should usually only set a (volatile) flag and return immediately, and should take extreme care if you really need to do more, is basically the first thing you learn when you read up on signal handlers. That's also completely obvious if you take a look at how they are implemented.)
- verytrivial 9y agoOh, I think we agree. Implementing the feature sounds like a right creeping pain for very little payoff. I would differ wrt "basically the first thing you learn when you read up on signal handlers" -- these days, the crazy kids writing code just start using the language and libraries. Learning why is usually the last thing learnt, and only when something, like a beeping-beep service, sets fire to something.
- jstimpfle 9y agoYep, if programmers can't be bothered to read a few lines of manpage before using a new function as distinctly special as signal()/sigaction(), then I think there is no help in sight. But on the other hand, the signals API might be a problem. Signals aren't exactly praised as a marvel of engineering. There probably is a need for something as low-level as that in some cases. But in the common case an API that just asynchronously sets a volatile flag when a signal is received, should be sufficient. Calls to "slow" devices are interrupted and return EINTR anyway.
- bpicolo 9y agoSeems like a good job for static analysis/linting vs compiler.
- amelius 9y agoPerhaps a better question is why signal handlers have these restrictions, and why they don't behave more like e.g. threads.
- jstimpfle 9y agoOther mechanisms have been designed, but they have different qualities. Probably none of them are as performant as signals, which might have been more important then than it is today. Creating a new thread for each single signal definitely feels wrong to me. Linux has signalfd() with which you can setup a signal-handling thread, but I think there are problems with that API as well. I think there is some value in being able to run a handler in the context of an existing thread the way traditional signals allow. (While I do vaguely remember that with common signals implementations it's very hard, or impossible, to control which thread is handling a signal).
- colanderman 9y agoBecause they were modeled after interrupts, and can't be changed for historical reasons. (E.g. any code which relies on the atomicity of a signal handler with respect to its context thread would break.) Signal handlers were always meant to be "top-half" interrupt handlers -- set a flag or put something in a queue for the main thread to process. signalfd(2) formalized this usage.