【发布时间】:2019-07-06 12:51:39
【问题描述】:
将信号处理程序设置为SIG_IGN 会在正常运行程序时忽略信号,但在通过 gdb 运行时不会。
我正在使用timer_create 和timer_settime 函数创建一个计时器。我不想使用信号处理程序(即函数)来处理此计时器生成的信号。我决定使用sigwait 并等待SIGALRM。我将SIGALRM 的处理程序设置为SIG_IGN 并使用sigwait。
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#define TRUE 1
#define ISTRUE(x) (x != 0)
#define bool int
int main() {
struct itimerspec timer_spec;
struct sigevent sig_event;
timer_t timer_id;
sigset_t sig_set;
timer_spec.it_interval.tv_sec = 1;
timer_spec.it_interval.tv_nsec = 0;
timer_spec.it_value.tv_sec = 1;
timer_spec.it_value.tv_nsec = 0;
sig_event.sigev_signo = SIGALRM;
sig_event.sigev_notify = SIGEV_SIGNAL;
signal(SIGINT, SIG_IGN);
signal(SIGALRM, SIG_IGN);
/* Create the timer */
timer_create(CLOCK_REALTIME, &sig_event, &timer_id);
timer_settime(timer_id, 0, &timer_spec, NULL);
sigemptyset(&sig_set);
sigaddset(&sig_set, SIGALRM);
int signal = 0;
bool running = TRUE;
while (ISTRUE(running)) {
sigwait(&sig_set, &signal);
switch(signal){
case SIGINT:
printf("Interrupt received.. exiting\n");
running = 0;
break;
case SIGALRM:
printf("Ticked\n");
break;
}
printf("Sleeping\n");
}
return 0;
}
在我的 IDE (CLion) 中调试应用程序以及从 shell 使用 gdb 时,程序按预期运行。 SIGALRM 没有被忽视,这让我相信我所做的是正确的。但是,正常运行应用程序,sigwait 永远不会返回。
后来我意识到这是因为信号被忽略了,我需要阻止信号(使用sigprocmask 或类似方法)并将其设置为挂起状态。
为什么在调试时信号会通过?这应该发生吗?我错过了什么?
【问题讨论】:
-
看来 ptrace 似乎以某种方式导致了这种情况,因为当程序在
strace下运行时也可以观察到这种行为。看起来像是一个有趣的 Linux 怪癖。