Linux下的segfault自重启程序

时间:2010-09-13 18:19:18

标签: c linux restart segmentation-fault recover

在Linux下,通过在崩溃处理程序中捕获异常(例如在段错误上),程序在崩溃时重启自身的最佳方法是什么?

7 个答案:

答案 0 :(得分:11)

最简单的是

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

基本上,你运行程序直到它返回0,然后你就会中断。

答案 1 :(得分:7)

SIGSEGV可以被捕获(请参阅man 3 signalman 2 sigaction),程序可以调用其中一个exec函数系列,以便重新启动。同样适用于大多数运行时崩溃(SIGFPESIGILLSIGBUSSIGSYS,...)。

但是,在做这个之前我会考虑一下。对于unix程序来说,这是一个相当不寻常的策略,你可能会让你的用户感到惊讶(也不一定以愉快的方式)。

在任何情况下,如果在死亡之前有任何想要清理的资源,请确保SIGTERM上自动重启,否则愤怒的用户将使用SIGKILL你会留下一团糟。

答案 2 :(得分:6)

您可以拥有一个基本上fork()的循环,完成孩子的实际工作,然后等待孩子并检查其在父母中的退出状态。您还可以使用以类似方式监视和重新启动程序的系统,例如daemontools,runit等。

答案 3 :(得分:3)

作为对此处提议内容的补充:

另一个选择就是为getty守护进程做的事情。请参阅/ etc / inittab和相应的inittab(5)手册页。它似乎是整个系统范围内的意思; - )。

它可能看起来像下面的文件片段。明显的优势这意味着非常标准,它允许通过运行级别控制您的守护进程。

# 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

答案 4 :(得分:1)

进程无法自行重启,但您可以使用crontab(1)之类的实用程序来安排脚本以定期检查进程是否仍处于活动状态。

答案 5 :(得分:1)

程序本身显然不应该检查它是否正在运行:)

对于给定的字符串,大多数企业解决方案实际上只是花费了ps()的输出,并且在满足某些条件的情况下执行操作 - 即如果找不到您的进程,则调用启动脚本。

答案 6 :(得分:0)

如果特定于segfault,请尝试以下代码。这可以根据需要进行修改。

#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)
}
相关问题