简体   繁体   中英

sigkill doesn't terminate C program

I'm under the impression that sigkill always works? I have a signal handler in my program that displays an exit prompt when you press Ctrl-C. That works fine but how do I also make it work when I kill through the command line? Right now the kill command does nothing. Is there something I'm supposed to implement in my code to make kill work?

You cannot set a signal handler for SIGKILL .

Your process does not get a chance to respond to SIGKILL . It is unilaterally terminated immediately; the process cannot do any clean up. The O/S releases the resources allocated to it, just as it does for any other dead process.

See POSIX Signal Concepts , and sigaction() , and (most particularly) <signal.h> — which says that SIGKILL and SIGSTOP cannot be caught or ignored.


OTOH, you say "how do I also make it so when I kill through the command line it also works". How do you plan to kill it? Assuming you have the PID in $pid , then:

kill $pid

sends a SIGTERM signal, and you can control which signal is sent by specifying it. The Control-C key normally sends SIGINT , usually signal number 2. The other signal sent from the keyboard is SIGQUIT ( Control-\\ ) or the various job control signals.

If you use:

kill -INT $pid

then that sends an interrupt ( SIGINT ) to the process (as would kill -2 $pid ). The default is equivalent to kill -TERM $pid . You'd send SIGKILL with one of:

kill -KILL $pid
kill -9 $pid

When you press control-C, that sends SIGINT, which your program can catch.
When you use the kill command, that sends SIGTERM by default, which your program can also catch.
But your program cannot catch or ignore SIGKILL. That's the one that's always guaranteed to be able to kill even a misbehaving program.

Read signal(7) & sigaction(2) and kill(1) (for the command) and kill(2) (for the system call).

By default, SIGTERM is sent by the kill command (eg kill 1234 is sending SIGTERM , using kill(2) , to process of pid 1234). Of course you can give an explicit signal in your kill command, eg kill -QUIT 1234 . You can catch it (eg SIGTERM or SIGQUIT ) by installing an appropriate signal handler.

Of course, you cannot catch SIGKILL (witch you could send with kill -KILL 1234 command), so you cannot set a signal handler for it (ie sigaction would give EINVAL error). Sending a SIGKILL always kills -ie terminates- the receiving targeted process (and should be used on rogue processes).

Regarding Ctrl C it is a complex thing related to tty-s (generally it is sending a SIGINT signal). Read the tty demystified ; etc... See also termios(3) & stty(1)

In practice, take the habit to kill your processes first with SIGTERM , then with SIGQUIT and at last with SIGKILL . Some processes (eg database servers) need some time to save a useful state to disk. So don't use kill -KILL at first (some processes might have an inconsistent state for their internal files, give them a chance to manage that with a "gentle" signal)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM