abhijeetviswa
abhijeetviswa

Reputation: 113

GDB, signals and SIG_IGN

Setting a signal handler as SIG_IGN ignores the signal while running the program normally but not while running it through gdb.

I'm creating a timer using timer_create and timer_settime functions. I don't want to use a signal handler (i.e a function) to handle the signals generated by this timer. I decided to use sigwait and wait for SIGALRM. I set the handler for SIGALRM as SIG_IGN and used 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;
}

While debugging the application in my IDE (CLion) as well as using gdb from the shell, the program functioned as expected. SIGALRM was not being ignored, which led me to believe that what I was doing was right. However, running the application normally, sigwait never returns.

I later realized that this was because the signal was being ignored and I needed to block the signal (using sigprocmask or similar) and set it to a pending state.

Why does, while debugging, the signal get passed through? Is this supposed to happen? What am I missing?

Upvotes: 1

Views: 1084

Answers (1)

user10678532
user10678532

Reputation:

You should look into the handle gdb command:

(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 ;-) ...

As mentioned in the manpage of ptrace(2) (which gdb is using):

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

Upvotes: 2

Related Questions