我有一个程序,该程序使用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
蜂鸣功能:
void sigterm(int signo)
{
logger_->info("SIGTERM received. Quitting.");
shutdown_if_->init_shutdown();
}
shutdown_if_
会触发将要写入的fd作为退出事件(使用pipe
创建)挂入轮询。
我期望发生的事情:该过程将在我抓住SIGTERM
之后继续,并将开始终止。取而代之的是,在捕获到信号之后,我将收到SIGSEGV
,因为似乎有些东西弄乱了。当我用调试器查看它时,整个堆栈似乎变得混乱(缺少局部变量等)。
当我在另一个带有信号的上下文中使用轮询的关闭功能时,一切正常,静态代码分析也找不到任何东西。我真的被困在这里。
如果您需要更多信息,请告诉我,我真的不知道如何解决这个问题。