On 11/12/20 5:25 PM, Heinrich Schuchardt wrote: [...] > Hello Michael, > > this text is very helpful. > > "Signal mask and pending signals" already mentions that the signal mask > controls the blocking of signals. But maybe you could reiterate this in > 1d) and in the note below 5). Yes, that perhaps does not hurt. Some light tweaks: Execution of signal handlers Whenever there is a transition from kernel-mode to user-mode exe‐ cution (e.g., on return from a system call or scheduling of a thread onto the CPU), the kernel checks whether there is a pending signal for which the process has established a signal handler. If there is such a pending signal, the following steps occur: 1. The kernel performs the necessary preparatory steps for execu‐ tion of the signal handler: a) The signal is removed from the set of pending signals. b) If the thread has defined an alternate signal stack (using sigaltstack(2)), then that stack is installed. c) Various pieces of signal-related context are saved into a "hidden" frame that is created on the stack. The saved in‐ formation includes: + the program counter register (i.e., the address of the next instruction in the main program that should be exe‐ cuted when the signal handler returns); + the thread's current signal mask; + the thread's alternate signal stack settings. d) The thread's signal mask is adjusted by adding the signal (unless the handler was established using the SA_NODEFER flag) as well as any additional signals specified in act->sa_mask when sigaction(2) was called. These signals are thus blocked while the handler executes. 2. The kernel constructs a frame for the signal handler on the stack. Within that frame, the return address points to a piece of user-space code called the signal trampoline (described in sigreturn(2)). 3. The kernel passes control back to user-space, where execution commences at the start of the signal handler function. 4. When the signal handler returns, control passes to the signal trampoline code. 5. The signal trampoline calls sigreturn(2), a system call that uses the information in the "hidden" stack frame to restore the thread's signal mask and alternate stack settings to their state before the signal handler was called. Upon completion of the call to sigreturn(2), the kernel transfers control back to user space, and the thread recommences execution at the point where it was interrupted by the signal handler. Note that if the signal handler does not return (e.g., control is transferred out of the handler using sigsetjmp(3) or swapcon‐ text(3), or the handler executes a new program with execve(2)), then the final step is not performed. In particular, in such sce‐ narios it is the programmer's responsibility to restore the state of the signal mask, if it is desired unblock the signals that were blocked on entry to the signal handler. Thanks, Michael -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/