Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linux C catching kill signal for graceful termination

Tags:

c

linux

kill

I have a process using sockets, database connections and the likes. It is basically a server process relaying between sensor data and a web interface, and as such it is important to ensure the application, if killed, terminates gracefully.

How do I handle unexpected exceptions such as segfaults (at least for debugging) as well as kill signals so that I can close any connections and stop any threads running so that the process does not leave a mess of anything it is using?

like image 312
user623879 Avatar asked Sep 11 '11 04:09

user623879


People also ask

Can SIGKILL be caught?

The SIGKILL signal is sent to a process to cause it to terminate immediately (kill). In contrast to SIGTERM and SIGINT, this signal cannot be caught or ignored, and the receiving process cannot perform any clean-up upon receiving this signal.

Which signal gracefully terminate the process?

The right signal for termination is SIGTERM and if SIGTERM doesn't terminate the process instantly, as you might prefer, it's because the application has chosen to handle the signal.

Which kill command signal will immediately stop a process with no graceful exit?

SIGKILL – The SIGKILL signal forces the process to stop executing immediately. The program cannot ignore this signal.

What is SIGTERM in Linux?

SIGTERM. (signal 15) is a request to the program to terminate. If the program has a signal handler for SIGTERM that does not actually terminate the application, this kill may have no effect. This is the default signal sent by kill. SIGKILL.


2 Answers

Catching signals is hard. You have to be careful. Your first step is to use sigaction to install a signal handler for the desired signals.

  • Choose a set of signals to respond to and choose what they mean for your process. For example, SIGTERM quits, SIGHUP restarts, SIGUSR1 reloads configuration, etc.

  • Don't try to respond to all signals and don't try to "clean up" after signal that indicates an error in your program. SIGKILL can't be caught. SIGSEGV, SIGBUS, and others like them shouldn't be caught unless you have a VERY good reason. If you want to debug, then raise the ulimit for core dumps — attaching a debugger to a core image is far more effective than anything you or I could ever code up. (If you do try to clean up after a SIGSEGV or something like that, realize that the cleanup code might cause an additional SIGSEGV and things could get bad quickly. Just avoid the whole mess and let SIGSEGV terminate your program.)

  • How you handle the signals is tricky. If your application has a main loop (e.g., select or poll) then the signal handler can just set a flag or write a byte to a special pipe to signal the main loop to quit. You can also use siglongjmp to jump out of a signal handler, but this is VERY difficult to get right and usually not what you want.

It's hard to recommend something without knowing how your application is structured and what it does.

Also remember that the signal handler itself should do almost nothing. Many functions are not safe to call from signal handlers.

like image 124
Dietrich Epp Avatar answered Sep 18 '22 11:09

Dietrich Epp


You install signal handlers to catch signals -- however in 99% of cases you just want to exit and let the Linux OS take care of the cleanup -- it will happily close all files, sockets, free memory and shutdown threads.

So unless there is anything specifically you want to do, like sending a message on the sockets, then you should just exit from the process and not try to catch the signal.

like image 32
Soren Avatar answered Sep 16 '22 11:09

Soren