I'm trying to find resources talking about handling synchronous signals (SIGSEGV, SIGILL etc.) compared to handling async signals.
The typical signal handling mechanism (using kill, for example) invokes signal handlers on control transfer from kernel to user mode. My understanding is that a 'synchronous' signal works more like a system call in that control transfers to kernel immediately - probably because synchronous signals are typically associated with CPU interrupts (memory protection etc.) and the kernel handler gets invoked for these anyway.
Are libc functions which are otherwise 'async-signal-unsafe' safe to be used in synchronous signal handlers? I see the Linux mprotect(2) man page uses printf inside a SIGSEGV handler, for example. How can I determine if a function can be used in these situations?
How does a typical Unix-like kernel's handling of synchronous signals differ from its handling of async signals? What makes them 'synchronous'?
There are no synchronous and asynchronous signals by nature, but some signals are delivered asynchronously and some other can be delivered sync or async.
Delivery is always the same: a signal handler in user mode is called if set. If not set then a default behavior is used (default behavior is terminating the process, except for some signals for which ignoring or pausing is done).
Signals are considered to be delivered asynchronously if they are initiated by some external cause (for example somebody else called
kill
). In such a case from the point of view of the process there is time in between emitting and delivering: process can execute many things...Signals are delivered synchronously if some internal runtime cause is detected for which a signal should be emitted. For example, a bad memory access which can deliver
SIGSEGV
orSIGBUS
, a floating point error like division by zero which deliverSIGFPE
, a bad instruction (SIGILL
), etc. In such a case it is the current executed code/instruction that is the source of the fault, then signal is immediately emitted and then delivered. In this case from the point of view of the process nothing happens in between emitting and delivery.