I sometimes get a little confused by all of the signals that a process can receive. As I understand it, a process has a default handler (signal disposition) for each of these signals, but it can provide its own handler by calling sigaction()
.
So here is my question: what causes each of the signals to be sent? I realize that you can manually send signals to running processes via the -s
parameter to kill
, but what are the natural circumstances under which these signals are sent? For example, when does SIGINT
get sent?
Also, are there any restrictions on which signals can be handled? Can even SIGSEGV
signals be processed and control returned to the application?
Best Answer
In addition to processes calling
kill(2)
, some signals are sent by the kernel (or sometimes by the process itself) in various circumstances:SIGINT
(please go back to the main loop) on Ctrl+C,SIGQUIT
(please quit immediately) on Ctrl+\,SIGTSTP
(please suspend) on Ctrl+Z. The keys can be changed with thestty
command.SIGTTIN
andSIGTTOU
are sent when a background process tries to read or write to its controlling terminal.SIGWINCH
is sent to signal that the size of the terminal window has changed.SIGHUP
is sent to signal that the terminal has disappeared (historically because your modem had hung up, nowadays usually because you've closed the terminal emulator window).SIGBUS
for an unaligned access memory;SIGSEGV
for an access to an unmapped page;SIGILL
for an illegal instruction (bad opcode);SIGFPE
for a floating-point instruction with bad arguments (e.g.sqrt(-1)
).SIGALRM
notifies that a timer set by the process has expired. Timers can be set withalarm
,setitimer
and others.SIGCHLD
notifies a process that one of its children has died.SIGPIPE
is generated when a process tries to write to a pipe when the reading end has been closed (the idea is that if you runfoo | bar
andbar
exits,foo
gets killed by aSIGPIPE
).SIGPOLL
(also calledSIGIO
) notifies the process that a pollable event has occured. POSIX specifies pollable events registered through theI_SETSIG
ioctl
. Many systems allow pollable events on any file descriptor, set via theO_ASYNC
fcntl
flag. A related signal isSIGURG
, which notifies of urgent data on a device (registered via theI_SETSIG
ioctl
) or socket.SIGPWR
is sent to all processes when the UPS signals that a power failure is imminent.These lists are not exhaustive. Standard signals are defined in
signal.h
.Most signals can be caught and handled (or ignored) by the application. The only two portable signals that cannot be caught are
SIGKILL
(just die) andSTOP
(stop execution).SIGSEGV
(segmentation fault) and its cousinSIGBUS
(bus error) can be caught, but it's a bad idea unless you really know what you're doing. A common application for catching them is printing a stack trace or other debug information. A more advanced application is to implement some kind of in-process memory management, or to trap bad instructions in virtual machine engines.Finally, let me mention something that isn't a signal. When you press Ctrl+D at the beginning of a line in a program that's reading input from the terminal, this tells the program that the end of the input file is reached. This isn't a signal: it's transmitted via the input/output API. Like Ctrl+C and friends, the key can be configured with
stty
.