За SIGTERM следует SIGSEGV - PullRequest
       23

За SIGTERM следует SIGSEGV

0 голосов
/ 26 октября 2018

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

Когда я использую функцию отключения опроса в другом контексте, что с сигналами все работает нормально, статический анализ кода также ничего не находит. Я действительно застрял здесь.

Скажите, пожалуйста, если вам нужна дополнительная информация, я не знаю, как решить эту проблему.

...