GDB、信号和 SIG_IGN

GDB, signals and SIG_IGN

将信号处理程序设置为 SIG_IGN 会在正常 运行 程序时忽略信号,但在通过 gdb 运行 时不会。

我正在使用 timer_createtimer_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从来没有returns。

我后来意识到这是因为信号被忽略了,我需要阻止信号(使用 sigprocmask 或类似的方法)并将其设置为挂起状态。

为什么调试的时候信号能通过?这应该发生吗?我错过了什么?

您应该查看 handle gdb 命令:

(gdb) handle SIGALRM
Signal        Stop      Print   Pass to program Description
SIGALRM       No        No      Yes             Alarm clock
(gdb) handle SIGALRM ignore
Signal        Stop      Print   Pass to program Description
SIGALRM       No        No      No              Alarm clock
(gdb) help handle
... read it ;-) ...

ptrace(2)gdb 使用)的联机帮助页中所述:

While being traced, the tracee will stop each time a signal is delivered, even if the signal is being ignored.