What causes various signals to be sent?
In addition to processes calling kill(2)
, some signals are sent by the kernel (or sometimes by the process itself) in various circumstances:
- Terminal drivers send signals corresponding to various events:
- Key press notifications:
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).
- Key press notifications:
- Some processor traps can generate a signal. The details are architecture and system dependent; here are typical examples:
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)
).
- A number of signals notify the target process that some system event has occured:
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.- On some systems,
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) and STOP
(stop execution).
SIGSEGV
(segmentation fault) and its cousin SIGBUS
(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
.
To answer your second question first: SIGSTOP
and SIGKILL
cannot be caught by the application, but every other signal can, even SIGSEGV
. This property is useful for debugging -- for instance, with the right library support, you could listen for SIGSEGV
and generate a stack backtrace to show just where that segfault happened.
The official word (for Linux, anyway) on what each signal does is available by typing man 7 signal
from a Linux command line. http://linux.die.net/man/7/signal has the same information, but the tables are harder to read.
However, without some experience with signals, it's hard to know from the short descriptions what they do in practice, so here's my interpretation:
Triggered from the keyboard
SIGINT
happens when you hitCTRL+C
.SIGQUIT
is triggered byCTRL+\
, and dumps core.SIGTSTP
suspends your program when you hitCTRL+Z
. UnlikeSIGSTOP
, it is catchable, which gives programs likevi
a chance to reset the terminal to a safe state before suspending themselves.
Terminal interactions
SIGHUP
("hangup") is what happens when you close your xterm (or otherwise disconnect the terminal) while your program is running.SIGTTIN
andSIGTTOU
pause your program if it tries to read from or write to the terminal while it's running in the background. ForSIGTTOU
to happen, I think the program needs to be writing to/dev/tty
, not just default stdout.
Triggered by a CPU exception
These mean your program tried to do something wrong.
SIGILL
means an illegal or unknown processor instruction. This might happen if you tried to access processor I/O ports directly, for example.SIGFPE
means there was a hardware math error; most likely the program tried to divide by zero.SIGSEGV
means your program tried to access an unmapped region of memory.SIGBUS
means the program accessed memory incorrectly in some other way; I won't go into details for this summary.
Process interaction
SIGPIPE
happens if you try to write to a pipe after the pipe's reader closed their end. Seeman 7 pipe
.SIGCHLD
happens when a child process you created either quits or is suspended (bySIGSTOP
or similar).
Useful for self-signaling
SIGABRT
is usually caused by the program calling theabort()
function, and causes a core dump by default. Sort of a "panic button".SIGALRM
is caused by thealarm()
system call, which will cause the kernel to deliver aSIGALRM
to the program after a specified number of seconds. Seeman 2 alarm
andman 2 sleep
.SIGUSR1
andSIGUSR2
are used however the program likes. They could be useful for signaling between processes.
Sent by the administrator
These signals are usually sent from the command prompt, via the kill
command, or fg
or bg
in the case of SIGCONT
.
SIGKILL
andSIGSTOP
are the unblockable signals. The first always terminates the process immediately; the second suspends the process.SIGCONT
resumes a suspended process.SIGTERM
is a catchable version ofSIGKILL
.