如何在按下“停止”按钮时捕获捆绑的GDB在clion中发出的信号?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在按下“停止”按钮时捕获捆绑的GDB在clion中发出的信号?相关的知识,希望对你有一定的参考价值。

在clion中进行调试时,有一个“停止”按钮(红色方块)可以停止正在运行的程序。目前,我正在编写测试并尝试调试它们。我的测试用例创建了临时目录和文件,应该在之后进行清理,但是按下按钮时都不会调用析构函数和信号处理程序。

这是我处理信号的方式(其中很多,因为我不确定GDB实际使用了哪些信号):

DLOG_S(INFO) << "Registering signal handlers for test files cleanup";
if (signal(SIGABRT, TemporaryDirectory::handle_cleanup) == SIG_ERR)
    DLOG_S(INFO) << "Registering SIGABRT failed";
if (signal(SIGTERM, TemporaryDirectory::handle_cleanup) == SIG_ERR)
    DLOG_S(INFO) << "Registering SIGTERM failed";
if (signal(SIGINT, TemporaryDirectory::handle_cleanup) == SIG_ERR)
    DLOG_S(INFO) << "Registering SIGINT failed";
if (signal(SIGALRM, TemporaryDirectory::handle_cleanup) == SIG_ERR)
    DLOG_S(INFO) << "Registering SIGALRM failed";

这是我的处理程序方法(它是静态的):

void test_utils::TemporaryDirectory::handle_cleanup(int signo) {
    DLOG_S(INFO) << "Received signal " << signo;
    if (signo == SIGABRT || signo == SIGTERM || signo == SIGINT || signo == SIGALRM) {
        DLOG_S(INFO) << "Cleaning up test files";
        TemporaryDirectory::test_files_root().cleanup();
    }
}

日志中没有注册失败消息,但我没有看到实际处理任何信号。

我也尝试通过在GDB控制台中输入handle all nostop来更改配置,但即使这样做,我的应用程序就会死掉。

clion捆绑的GDB停止后有没有办法清理?

答案

据我所知,当您在调试程序时单击Stop按钮时,CLion将:

  • 如果目标尚未停止,则向目标进程发送SIGINT信号,然后从gdb读取有关已收到信号的目标的响应(如果有)
  • 向gdb发送一个kill命令,这将导致gdb用一个无法捕获的,不可忽视的SIGKILL信号杀死目标
  • -gdb-exit命令发送到gdb,这将导致gdb退出

如果发送了SIGINT,并且您的程序中有一个SIGINT处理程序,并且您已配置gdb以将信号传递给目标,例如handle SIGINT pass nostop noprint,目标将运行其SIGINT处理程序,但稍后将被kill命令杀死。

如果您想通过调用信号处理程序为程序提供清理机会,可以使用kill命令重新定义gdb的signal命令以发送您选择的信号:

define kill
  signal SIGTERM
  shell sleep 5
end

(OP已经表示,事情可以按照需要运行而不需要shell sleep 5。)

另一答案

要在gdb中处理信号,请在调试会话中使用handle signal keywords...。更多细节:https://sourceware.org/gdb/onlinedocs/gdb/Signals.html

顺便说一句,它不是gdb发送信号,而是内核。

以上是关于如何在按下“停止”按钮时捕获捆绑的GDB在clion中发出的信号?的主要内容,如果未能解决你的问题,请参考以下文章

需要在按下按钮时“刷新”应用程序的屏幕

Android:如何在按下按钮时关闭一个活动并在按下另一个按钮时关闭整个后台堆栈? [复制]

如何在按下 UIButton 的按钮时关闭按钮阴影?

如何在按下按钮后每 10 分钟重复一次方法并在按下另一个按钮时结束它

如何仅在按下按钮时更新位置

xctest - 如何测试是不是在按下按钮时加载新视图