Самостоятельно перезапустить программу на segfault под Linux - PullRequest
3 голосов
/ 13 сентября 2010

В Linux, каков был бы лучший способ для перезапуска программы в случае сбоя путем перехвата исключения в обработчике сбоя (например, в segfault)?

Ответы [ 7 ]

11 голосов
/ 13 сентября 2010

самое простое -

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

в основном, вы запускаете программу до тех пор, пока она не вернет 0, а затем прерываете.

7 голосов
/ 13 сентября 2010

SIGSEGV может быть перехвачено (см. man 3 signal или man 2 sigaction), и программа может вызвать одну из функций семейства exec для перезапуска.Аналогично для большинства сбоев во время выполнения (SIGFPE, SIGILL, SIGBUS, SIGSYS, ...).

Я бы немного подумал, прежде чем делать это.Это довольно необычная стратегия для Unix-программ, и вы можете удивить своих пользователей (не обязательно приятным способом).

В любом случае, обязательно , а не с автоматическим перезапуском на SIGTERM, если есть какие-то ресурсы, которые вы хотите очистить перед смертью, иначе рассерженные пользователи будут использовать SIGKILLоставлю беспорядок.

6 голосов
/ 13 сентября 2010

Вы можете иметь цикл, в котором вы, по сути, fork(), выполняете реальную работу с дочерним элементом, и просто ждете дочернего элемента и проверяете его статус выхода в родительском элементе.Вы также можете использовать систему, которая аналогичным образом отслеживает и перезапускает программы, такие как daemontools, runit и т. Д.

3 голосов
/ 13 сентября 2010

В качестве дополнения к тому, что было предложено здесь:

Другой вариант - сделать так, как это делается для демона 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
1 голос
/ 13 сентября 2010

Сама программа, очевидно, не должна проверять, запущена она или нет:)

Большинство корпоративных решений на самом деле представляют собой просто причудливые способы получения результата из ps() для заданной строки и выполнения действия в случае, если определенные критерии удовлетворены - например, если ваш процесс не найден, тогда вызовите стартовый скрипт .

1 голос
/ 13 сентября 2010

Процессы не могут перезапускать себя, но вы можете использовать утилиту, такую ​​как crontab(1), чтобы запланировать сценарий проверки того, что процесс все еще жив через регулярные интервалы.

0 голосов
/ 27 марта 2012

Попробуйте следующий код, если он относится к 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)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...