24.1.3 How Signals Are Delivered

When a signal is generated, it becomes pending. Normally it
remains pending for just a short period of time and then is
delivered to the process that was signaled. However, if that kind
of signal is currently blocked, it may remain pending
indefinitely—until signals of that kind are unblocked. Once
unblocked, it will be delivered immediately. See Blocking Signals.

When the signal is delivered, whether right away or after a long delay,
the specified action for that signal is taken. For certain
signals, such as SIGKILL and SIGSTOP, the action is fixed,
but for most signals, the program has a choice: ignore the signal,
specify a handler function, or accept the default action for
that kind of signal. The program specifies its choice using functions
such as signal or sigaction (see Signal Actions). We
sometimes say that a handler catches the signal. While the
handler is running, that particular signal is normally blocked.

If the specified action for a kind of signal is to ignore it, then any
such signal which is generated is discarded immediately. This happens
even if the signal is also blocked at the time. A signal discarded in
this way will never be delivered, not even if the program subsequently
specifies a different action for that kind of signal and then unblocks
it.

If a signal arrives which the program has neither handled nor ignored,
its default action takes place. Each kind of signal has its own
default action, documented below (see Standard Signals). For most kinds
of signals, the default action is to terminate the process. For certain
kinds of signals that represent “harmless” events, the default action
is to do nothing.

When a signal terminates a process, its parent process can determine the
cause of termination by examining the termination status code reported
by the wait or waitpid functions. (This is discussed in
more detail in Process Completion.) The information it can get
includes the fact that termination was due to a signal and the kind of
signal involved. If a program you run from a shell is terminated by a
signal, the shell typically prints some kind of error message.

The signals that normally represent program errors have a special
property: when one of these signals terminates the process, it also
writes a core dump file which records the state of the process at
the time of termination. You can examine the core dump with a debugger
to investigate what caused the error.

If you raise a “program error” signal by explicit request, and this
terminates the process, it makes a core dump file just as if the signal
had been due directly to an error.