4 ms·
A weird (at first sight) thing about signal handlers - the kernel doesn't really know, or care, if you're running in one. Which makes sense because signal hand
by mark_undoio 3y ago
A weird (at first sight) thing about signal handlers - the kernel doesn't really know, or care, if you're running in one.
Which makes sense because signal handlers can nest, so ideally the kernel wouldn't have to maintain some state for each enter/exit of signal handlers to be tracked.
Instead, the kernel sets up the necessary conditions for things to act like a signal handler expects and puts some state on your the stack representing your registers, active signal mask, etc, plus some state to ensure a sigreturn syscall will run.
If you return from your handler, that'll take effect and your state is restored to where you were before. If you go into a nested signal handler, the kernel pushes another pile of state on the stack to return to where you are now.
You're free to change that saved state before returning - or just siglongjmp out of there and discard it, if you know what you're doing.
Libc is a lot more tricky about signals, since not all libc functions can be safely called from handlers. From the kernel's point of view, there's nothing magic about them at all but usually we're stuck with libc restrictions into the bargain.
- 10000truths 3y agoIt also makes sense because the kernel has no way of knowing. When you exec a binary, all that the kernel sees is an ELF image with a blob of bytes in the .text section. It doesn't know which part(s) of those blob of bytes is a signal handler. Even if it did know, the kernel has no way of verifying that the function is only ever invoked by the signal (userspace could manually call the signal handler function).
- ptsneves 3y ago> Libc is a lot more tricky about signals, since not all libc functions can be safely called from handlers. And this is a huge thing. People do all kinds of operations in signal handlers completely oblivious to the pitfalls. Pitfalls which often do not manifest, making it a great "it works for me" territory. I once raised a ticket on fluentbit[1] about it but they have abused signal handlers so thoroughly that I do not think they can mitigate the issue without a major rewriting of the signal and crash handling. [1] https://github.com/fluent/fluent-bit/issues/4836 https://github.com/fluent/fluent-bit/issues/4836
- jlokier 3y agoCalls to printf() are particularly common in signal handlers I've seen in commercial code. malloc() too occasionally. Sometimes calls to logging functions These are undefined behaviour, for real (and for good reasons), not just theoretically. They are a cause of reported occasional random crashes, but people don't realise, and it's tricky to demonstrate or warn at compile time.