У меня есть программа, которая использует epoll
для ожидания определенных событий (например, данных, доступных в сокете и т. Д.). Эта программа работает как служба, запущенная systemd
. Чего я хочу добиться, так это правильного выключения. Поэтому я установил обработчик сигнала, который поймает SIGTERM
. Насколько я понимаю, systemd
сначала отправит SIGTERM
, а затем SIGKILL
после задержки, поэтому у процесса есть шанс на правильное завершение.
Мой обработчик сигнала выглядит так:
struct sigaction act;
::memset(&act, 0, sizeof(struct sigaction));
act.sa_flags = SA_RESTART;
act.sa_handler = sigterm;
if (sigaction(signal, &act, NULL) == -1)
{
logger_.explode("Error setting up signal %d (%d)", signal, errno);
}
С моей функцией sigterm
beeing:
void sigterm(int signo)
{
logger_->info("SIGTERM received. Quitting.");
shutdown_if_->init_shutdown();
}
Принимая во внимание, что shutdown_if_
запустит запись fd, которая будет повешена в опросе как событие выхода (созданное с помощью pipe
).
То, что я ожидаю, произойдет: процесс будет продолжаться, так как я поймал SIGTERM
и начну останавливаться. Вместо этого, после того, как сигнал будет перехвачен, я получу SIGSEGV
, поскольку что-то, кажется, испорчено. Когда я смотрю на него с помощью отладчика, весь стек кажется испорченным (локальные переменные отсутствуют и т. Д.).
Когда я использую функцию отключения опроса в другом контексте, что с сигналами все работает нормально, статический анализ кода также ничего не находит. Я действительно застрял здесь.
Скажите, пожалуйста, если вам нужна дополнительная информация, я не знаю, как решить эту проблему.