开发者

Self restart program on segfault under Linux

Under Linux what would be the best way开发者_如何学Go for a program to restart itself on a crash by catching the exception in a crashhandler (for example on a segfault)?


simplest is

while [ 1 ]; do ./program && break; done

basically, you run program until it is return 0, then you break.


You can have a loop in which you essentially fork(), do the real work in the child, and just wait on the child and check its exit status in the parent. You can also use a system which monitors and restarts programs in a similar fashion, such as daemontools, runit, etc.


SIGSEGV can be caught (see man 3 signal or man 2 sigaction), and the program can call one of the exec family of function on itself in order to restart. Similarly for most runtime crashes (SIGFPE, SIGILL, SIGBUS, SIGSYS, ...).

I'd think a bit before doing this, though. It is a rather unusual strategy for a unix program, and you may surprise your users (not necessarily in a pleasant way, either).

In any case, be sure to not auto-restart on SIGTERM if there are any resources you want to clean up before dying, otherwise angry users will use SIGKILL and you'll leave a mess.


As a complement to what was proposed here:

Another option is to do like it is done for getty daemon. Please see /etc/inittab and appropriate inittab(5) man page. It seems it is most system-wide mean ;-).

It could look like file fragment below. Obvious advantage this mean is pretty standard and it allows to control your daemon through run levels.

# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6


Processes can't restart themselves, but you could use a utility like crontab(1) to schedule a script to check if the process is still alive at regular intervals.


The program itself obviously shouldn't check whether it is running or not running :)

Most enterprise solutions are actually just fancy ways of grepping the output from ps() for a given string, and performing an action in the event that certain criteria are satisfied - i.e. if your process is not found, then call the start script.


Try the following code if its specific to segfault. This can be modified as required.

#include <stdio.h> 
#include <signal.h> 
#include <setjmp.h> 
#include <poll.h>

sigjmp_buf buf; 
void handler(int sig) { 
siglongjmp(buf, 1); 
} 
int main() { 
//signal(SIGINT, handler); 
//register all signals
struct sigaction new_action, old_action;
new_action.sa_handler = handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;

sigaction (SIGSEGV, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGSEGV, &new_action, NULL);

if (!sigsetjmp(buf, 1)){
printf("starting\n"); 
//code or function/method here
}
else{  
printf("restarting\n"); 
 //code or function/method here
}
while(1) {
poll(NULL,0,100); //ideally use usleep or nanosleep. for now using poll() as a timer
printf("processing...\n");
}
return 0; //or exit(SUCESS)
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜