首页 > 解决方案 > SIGTERM 后面是 SIGSEGV

问题描述

我有一个程序用于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并且将开始终止。取而代之的是,在捕获信号后,我将收到 a SIGSEGV,因为某些东西似乎搞砸了。当我用调试器查看它时,整个堆栈似乎一团糟(缺少局部变量等)。

当我在另一个带有信号的上下文中使用轮询的关闭功能时,一切正常,静态代码分析也找不到任何东西。我真的被困在这里了。

如果您想了解更多信息,请告诉我,我真的不知道如何解决这个问题。

标签: c++linuxsignalsepoll

解决方案


推荐阅读