无法捕获由CLion发送的SIGINT信号

3
我正在使用CLion开发一些网络编程项目。由于我正在使用socket,如果我不干净地关闭我正在使用的socket和其他网络对象,那么程序将会阻塞端口,我必须使用命令行来手动关闭它。
考虑到我需要在每个测试之间执行此操作,这非常麻烦。因此,我寻找了一种当您单击“停止”时CLion终止程序的方法,并发现它发送SIGINT信号,在这里:
单击此按钮可以通过标准关闭脚本外部终止当前进程。单击该按钮一次会调用软杀死以允许应用程序捕获SIGINT事件并执行优雅终止(在Windows上,Ctrl + C事件被模拟)。单击该按钮后,它将被替换为运行工具窗口kill图标,表示后续单击将导致强制终止应用程序,例如在Unix上发送SIGKILL。
然后,我尝试捕获它,但出于某些原因,它不起作用。所以我尝试创建一个新项目,其中我只是试图捕获SIGINT信号。以下是一个非常简单但无效的示例:
#include <iostream>

void signalHandling(int signal)
{
    std::cout << "Signal : " << signal << std::endl;
}

int main() {
    signal(SIGINT, signalHandling);
    while (1)
    {
        ;
    }
}

我收到的信息只有:进程退出代码为1

所以,我的问题是:为什么我无法捕获由CLion发送的(或者至少应该发送的)这个信号呢?

如果可能与我的环境有关,那么我使用的是CLion 2018.1.5,我的工具链是Cygwin,我正在使用cmake 3.10.3。我正在使用Windows 10操作系统。


即使您没有清楚地关闭套接字,程序也不能在进程退出后阻止端口。 您只能在信号处理程序中使用异步信号安全函数。 您确定信号处理程序实际上被安装了吗? 而且,信号处理也不是在其他某个地方执行的吗? - user7860670
另外,您是在调试会话中尝试还是普通启动中尝试的?看起来CLion在调试会话中直接使用SIGKILL - eerorika
无法捕获 SIGKILL 信号。我认为你应该尝试从普通控制台运行程序,并手动按下 Ctrl+C 发送 SIGINT 信号。顺便问一下,为什么你设置了 SIGQUIT 的处理程序而不是 SIGINT - user7860670
@VTT 对于 SIGQUIT 我的错误,只是尝试了一些东西并忘记将其改回 SIGINT。实际上,我按下了 CLion 的“停止”按钮,这个按钮应该发送信号。是的,我在普通控制台中。 - souki
我的意思是你应该在没有CLion的情况下检查这段代码。也许它会错误地发送Ctrl+C或其他什么东西。 - user7860670
显示剩余8条评论
2个回答

4

从@VTT的帮助中,我得出如下结论。

提供的示例应该是有效的,在不使用CLion时确实有效。 我实际上在终端上尝试了CTRL-C,它也可以工作。我的程序接收到了SIGINT信号。

因此,这个问题很可能是CLion的一个bug,因为停止按钮实际上应该模拟CTRL-C并发送SIGINT信号。

我已向JetBrains团队发送了错误报告,并将等待他们的反馈并让您知道。

再次感谢@VTT。


编辑:

我联系了CLion支持,他们只是将我重定向到由另一个CLion用户编写的另一个类似问题。所以我想他们不会采取任何措施。

经过一些研究,我找到了这个问题。几乎相同,除了它说CLion不能正确地杀死进程,这就是我的情况。

显然,这是由于他们的停止脚本引起的bug。我找到了一种让CLion实际结束进程的方法。

警告!

您应该知道更改注册表选项可能是危险的! 使用以下解决方案时要自行承担风险!

这就是我所做的:

  • 点击“帮助”
  • 点击“查找操作”
  • 输入并选择“Registry”
  • 取消勾选run.processes.with.pty

就是这样!

您必须知道,这不会允许您捕获CLion“停止”按钮应该发送的SIGINT信号,但它确实会杀死进程,而不像停止按钮。 还请注意,这不是问题的真正答案,但由于我正在进行编程项目,因此必须手动终止我的服务器以再次运行它。所以它解决了我的问题,并可能解决其他人的问题。


0

我正在寻找相同的问题,遇到了由Employed Russian提供的以下answer。它并不理想,但是我能够将SIGINT传递给我的进程并优雅地退出(在我的情况下,那就是我的意图)。

我不喜欢这种方法的原因是你需要做太多步骤:

  1. 配置注册表以发送SIGINT而不是SIGSTOP(警告类似于Souki的答案)
  2. 每当您想要停止->暂停进程。
  3. 发送命令handle SIGTRAP nostop noprint pass
  4. 继续进程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接