LINUX.ORG.RU

Перезапуск при SIGSEGV

 


0

1

Допустим, есть демон, который поймал SIGSEGV. Допустим, он сохранил backtrace в лог. Далее нам нужно прекратить выполнение процесса, и, желательно, перезапуститься. Просто прекратить выполнение - банально, хочется разобраться с перезапуском. fork() с последующим execve() должен работать. Но мне кажется, что fork() здесь не обязателен. Так ли это?

backtrace

ЕМНИП в обработчике сигнала там будет мусор. Для сбора дампа в таком состоянии есть библиотека Google Breakpad, которая написана с учётом правил обработки сигналов.

fork() с последующим execve() должен работать. Но мне кажется, что fork() здесь не обязателен. Так ли это?

Я не уверен, что эти функции будут работать в обработчике сигнала. Увы. И всё же, можно погуглить, как firefox запускает новый процесс после креша. Там должен быть ответ и на этот вопрос.

quiet_readonly ★★★★ ()
Ответ на: комментарий от quiet_readonly

Конкретика по бэктрэйсу выходит за рамки темы.

man 7 signal говорит, что fork() и execve() безопасны для использования в обработчике сигнала.

Отсылка к firefox принимается, хотя было бы лучше уже сразу с конкретикой, так как я подозреваю, что там настолько всё косвенно и завуалировано либами и фреймворками, что до сути там будет не добраться при беглом прочтении.

Krieger_Od ★★ ()

пусть сохраняет core файл. перезапуск лучше делать инитом или в крайнем случае по крону.

x0r ★★★★★ ()
Ответ на: комментарий от x0r

перезапуск лучше делать инитом

Как конкретно вы предлагаете это сделать из программы? О monit и других службах мониторинга давайте не будем.

Krieger_Od ★★ ()
Ответ на: комментарий от quiet_readonly

И всё же, можно погуглить, как firefox запускает новый процесс после креша

Банально, /usr/bin/firefox - это скрипт, который запускает бинарник и проверяет его код возврата.

alex_custov ★★★★★ ()
Ответ на: комментарий от Krieger_Od

Как конкретно вы предлагаете это сделать из программы?

если программа словила SIGSEGV - не самая лучшая идея рестартовать её из самой себя.

всего 2 вопроса: 1) что делать если sigsegv придёт до установки обработчика сигнала ? 2) что делать если после установки обработчика перманентно случается sigsegv?

dhampire ★★★ ()

ЕМНИП в обработчике сигнала там будет мусор.

отнюдь

1) что делать если sigsegv придёт до установки обработчика сигнала ? 2) что делать если после установки обработчика перманентно случается sigsegv?

писать прямыми руками

Банально, /usr/bin/firefox - это скрипт, который запускает бинарник и проверяет его код возврата.

true way.

dib2 ★★★★★ ()
Ответ на: комментарий от Krieger_Od

в том и дело, что не из программы. демоны запускаются инит скриптом или системд юнитом, они пусть и следят.

в системд это будет выглядить так:

[Service]
Restart=on-abort

If set to on-abort, the service will be restarted only if the service process exits due to an uncaught signal not specified as a clean exit status.

x0r ★★★★★ ()
Ответ на: комментарий от dib2

Банально, /usr/bin/firefox - это скрипт, который запускает бинарник и проверяет его код возврата.

true way

Банально и правильно, да. Но ведь и fork + execve тоже достаточно просто. Я вообще спрашивал о необходимости fork здесь.

Krieger_Od ★★ ()
Ответ на: комментарий от Krieger_Od

вообще поведение системных вызовов в обработчике сигналов, особенно с поврежденной кучей или стеком, не всегда предсказуемо и стабильно. записали бэктрейс и будьте счастливы, освобождайте память. иногда можно и запись не получить, а скрипт может дать 2>&1 и код возврата прямо в лог, что есть гуд в решении особенно противных ситуаций

dib2 ★★★★★ ()

Можно делать на цепочке форков. Watchdog -> KeepAlive -> Daemon. Как только процесс daemon завершается, сразу аккуратно завершается процесс KeepAlive и посылает сигнал SIGCHLD на watchdog. Параллельно какой-то из процессов может проверять /proc/PID

Немного сложно и малость многоресурсно, но весьма надежно.

gh0stwizard ★★★★★ ()

Можно просто execv, без fork. Тогда даже pid тот же останется.

Moncruist ()
Ответ на: комментарий от Krieger_Od

Банально и правильно, да. Но ведь и fork + execve тоже достаточно просто.

Это не просто если учитывать все нюансы этой последовательности. Например, незакрытые файловые дескрипторы после exec, мб ещё чего будет.

mashina ★★★★★ ()

Можно просто exec прямо в обработчике. Но надо учесть, что сегфолт не от скуки прилетает. Не самая редкая причина — переполнение буфера, может затереть оригинальные аргументы командной строки и переменные окружения. Можно перезапускать с пустыми или с некоторыми захардкоженными в константных строках. Но тогда надо предусмотреть какое-то разумное поведение демона, когда он будет так запущен.

const86 ★★★★★ ()

Самостоятельный перезапуск ненадежен, т.к. при некоторых фейлах даже fork() не успеешь вызвать. Так что только слежение и перезапуск извне.

Pavval ★★★★★ ()
Ответ на: комментарий от Krieger_Od

Ты нас тоже. Перезапуск самостоятельный не надежен, и это в компетенции системы инициализации или вотчдогов. Демон может не освободить дескрипторы, локи. Выше уже упоминали другие потенциальные проблемы. Такой код я бы не пропустил в проект.

anonymous ()
Ответ на: комментарий от quiet_readonly

И всё же, можно погуглить, как firefox запускает новый процесс после креша.

что там гуглить? Открой run-mozilla.sh

emulek ()
Ответ на: комментарий от emulek

ВНЕЗАПНО: уже нет.

λ desktop ~ → file $(which firefox)
/usr/bin/firefox: symbolic link to `../lib/firefox/firefox.sh'
theNamelessOne ★★★★★ ()
Ответ на: комментарий от quiet_readonly

ЕМНИП в обработчике сигнала там будет мусор. Для сбора дампа в таком состоянии есть библиотека Google Breakpad, которая написана с учётом правил обработки сигналов.

Что за ерунда? Делаешь обработчик, принимающий контекст

esandmann ()

В описанной тобой ситуации fork просто лишний. Если хочешь сделать rexec - делай сразу из обработчика сигнала. Но единственное надежное решение - fork до начала выполнения функций демона на рабочий процесс и сторожа, немедленное завершение рабочего процесса по сигналу, и перезапуск рабочего процесса сторожем.

tailgunner ★★★★★ ()

Запускай два процесса.

Reset ★★★★★ ()
Ответ на: комментарий от tailgunner

+1

А перед exec еще и prctl(PR_SET_PDEATHSIG) навесить, чтобы убийство watchdog'а убивало и воркера.

Reset ★★★★★ ()

Я бы за перезапуск из обработчика расстрелял бы например.

nanoolinux ★★★★ ()

Есть же православный daemon, который все с удовольствием сделает за вас. Зачем использовать что-то еще?

anonymous ()

Далее нам нужно прекратить выполнение процесса, и, желательно, перезапуститься

И опять получить SIGSEGV? Может, стоит починить это?

hateyoufeel ★★★★★ ()

Если тебе хочется, чтобы процесс обязательно перезапустился после падения, тебе стоит воспользоваться программами, которые следят за процессами. Таким функционалом обладает программа init, та самая, которая конфигурируется в /etc/inittab.

pathfinder ★★★★ ()
Ответ на: комментарий от hateyoufeel

И опять получить SIGSEGV? Может, стоит починить это?

Не надо путать разработку и выпуск продукта. Понятно, что на стадии тестирования и отладки софта такие штуки не нужны.

pathfinder ★★★★ ()
Последнее исправление: pathfinder (всего исправлений: 1)

И продолжить рабоnать с, например, попорченой памятью.. Лучше сделать watchdog или простенкий стартер который перезапускает приложение после выхода

vromanov ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.