I have a program that uses epoll to wait for certain events (like data available in a socket, etc). This program is running as a service started by systemd. What I want to achieve is a proper shutdown. So I have installed a signal handler that will catch the SIGTERM. From my understanding, systemd will first send a SIGTERM followed by a SIGKILL after a delay, so the process has the chance for a proper shutdown.
My signal handler looks like this:
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);
}
With my function of sigterm beeing:
void sigterm(int signo)
{
logger_->info("SIGTERM received. Quitting.");
shutdown_if_->init_shutdown();
}
Whereas shutdown_if_ will trigger a fd to be written to that is hanged into the poll as as quit event (created with pipe).
What I expect to happen: The process will continue as I have catched the SIGTERM and will begin to terminate. Instead of that, after the signal is catched, I will receive a SIGSEGV as something seems to be messed up. When I look at it with a debugger the whole stack seems to be hella messed up (local variables missing, etc).
When I use the shutdown function of the poll in another context that with signals, everything works fine, static code analysis does not find anything as well. I am really stuck here.
Please tell me if you want any more informations, I do not really know how to put this problem.