GDB, сигналы и SIG_IGN - PullRequest
       25

GDB, сигналы и SIG_IGN

3 голосов
/ 06 июля 2019

Установка обработчика сигнала как 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), а также при использовании gdb из оболочки программа функционировала так, как ожидалось. SIGALRM не был проигнорирован, что заставило меня поверить, что то, что я делал, было правильно. Однако при нормальном запуске приложения sigwait никогда не возвращается.

Позже я понял, что это потому, что сигнал игнорировался, и мне нужно было заблокировать сигнал (используя sigprocmask или аналогичный) и установить его в состояние ожидания.

Почему при отладке сигнал проходит? Это должно случиться? Чего мне не хватает?

1 Ответ

2 голосов
/ 06 июля 2019

Вы должны заглянуть в команду 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):

Во время трассировки трассировка будет останавливаться при каждой доставке сигнала, даже если сигнал игнорируется.

...