How signals work internally

Architecturekillsignals

In general, to kill processes we generate signals like SIGKILL,SIGTSTP etc.

But how is it known who ordered that particular signal, who has sent it to a particular process, and in general how do signals perform their operations? How do signals internally work?

Best Answer

The 50,000 foot view is that:

  1. A signal is generated either by the kernel internally (for example, SIGSEGV when an invalid address is accessed, or SIGQUIT when you hit Ctrl+\), or by a program using the kill syscall (or several related ones).

  2. If it’s by one of the syscalls, then the kernel confirms the calling process has sufficient privileges to send the signal. If not, an error is returned (and the signal doesn't happen).

  3. If it’s one of two special signals, the kernel unconditionally acts on it, without any input from the target process. The two special signals are SIGKILL and SIGSTOP. All the stuff below about default actions, blocking signals, etc., are irrelevant for these two.

  4. Next, the kernel figures out what do with the signal:

    1. For each process, there is an action associated with each signal. There are a bunch of defaults, and programs can set different ones using sigaction, signal, etc. These include things like "ignore it completely", "kill the process", "kill the process with a core dump", "stop the process", etc.

    2. Programs can also turn off the delivery of signals ("blocked"), on a signal-by-signal basis. Then the signal stays pending until unblocked.

    3. Programs can request that instead of the kernel taking some action itself, it deliver the signal to the process either synchronously (with sigwait, et. al. or signalfd) or asynchronously (by interrupting whatever the process is doing, and calling a specified function).

There is a second set of signals called "real-time signals", which have no specific meaning, and also allow multiple signals to be queued (normal signals queue only one of each when the signal is blocked). These are used in multi-threaded programs for the threads to communicate to each other. Several are used in glibc's POSIX threads implementation, for example. They can also be used to communicate between different processes (for example, you could use several real-time signals to have a fooctl program send a message to the foo daemon).

For a non-50,000 foot view, try man 7 signal and also the kernel internals documentation (or source).

Related Question