kill -9 and POSIX signals?!— October 6, 2018
It’s 3:30AM on a Saturday, and I’m currently working on a shell in Go. I’m trying to recall how to trap signals in Go, and
kill -9 came to my mind. All I knew was that the command “terminates a program”, but why is it actually the case? I don’t understand it well, so I’m going to explore how the
kill command and signal actually works.
man kill shows:
SYNOPSIS kill [-s signal_name] pid ... kill -l [exit_status] kill -signal_name pid ... kill -signal_number pid ...
I didn’t know 9 is actually the signal number! Interesting. So, a signal is actually used for sending information between processes or between the kernel and a process.
Here is a high level overview on how I think signals are used:
kill -9 <pid>gets the
killutility to make a syscall to generate a SIGKILL signal in the kernel, and this terminates the process pid.
- Whenever an invalid memory address is accessed, the kernel generates a SIGSEGV signal, and this results in the termination of the process with a segmentation fault.
- Whenever the user presses Ctrl + C on the keyboard, the kernel sends the SIGINT signal to the shell process, which then sends it to the process.
There are many different signal types, and we can list all of them through
kill -l or
bash-3.2$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGEMT 8) SIGFPE 9) SIGKILL 10) SIGBUS 11) SIGSEGV 12) SIGSYS 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGURG 17) SIGSTOP 18) SIGTSTP 19) SIGCONT 20) SIGCHLD 21) SIGTTIN 22) SIGTTOU 23) SIGIO 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGINFO 30) SIGUSR1 31) SIGUSR2
The common ones are
SIGINT(2) (Ctrl + C),
SIGQUIT(3) (Ctrl + D),
SIGTERM(15). By default,
kill without the signal name will use SIGTERM. This will ask the process to terminate as soon as it possibly can (i.e. graceful shutdown).
So, how can we actually get the shell process to send it to the inner process? We need traps. Traps allow us to trap some or all of these signals that the kernel sends to the process, and the process could then perform operations on the trapped signal.
We can create a trap for specific signals in our shell process, and when it receives those signals, it can act accordingly, such as forwarding it to the inner process or terminating it, in the case of a SIGINT.
Also, a quick look at the linux kernel source code shows the following fact:
SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.
kill -9 <pid>can be translated into:
- Don’t run
kill -9just because
killdoesn’t work. Only do this as a last resort.
- You cannot SIGKILL pid 1 (
initon Linux /
launchdon Mac OSX). This is done to assure that the system is not brought down accidentally.
I should probably play with
strace someday. I wonder what shows up for these