在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停止后有没有办法清理?
答案 0 :(得分:1)
据我所知,当您在调试程序时单击Stop
按钮时,CLion会:
SIGINT
信号,然后从gdb中读取有关已收到信号的目标的响应(如果有)kill
命令,这将导致gdb使用无法捕获的,不可忽视的SIGKILL
信号杀死目标-gdb-exit
命令,这将导致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
。)
答案 1 :(得分:0)
要在gdb中处理信号,请在调试会话中使用handle signal keywords...
。更多详情:https://sourceware.org/gdb/onlinedocs/gdb/Signals.html
顺便说一句;它不是gdb向你发送信号,它是内核。