Я хочу знать, какой сигнал поступает, когда системный вызов () прерывается

Мое приложение имеет две темы. Каждый поток получает некоторые данные с сервера через каждый сокет. Потоки ждут возврата epoll_wait(). Иногда epoll_wait () возвращает -1, а errno - EINTR. EINTR означает, что системный вызов () прерывается сигналом. Я добавил в процесс EINTR. Однако я не знаю, какой сигнал поступил и почему пришел сигнал. Интересно.

Способ 1

Я создал тему.

sigset_t sMaskOfSignal;                                               
sigset_t sOldMaskOfSignal;                                            
sigfillset(&sMaskOfSignal);                                           
sigprocmask(SIG_UNBLOCK, &sMaskOfSignal, &sOldMaskOfSignal)

while(1)
{                                                                                        
    sigwait(&sMaskOfSignal, &sArrivedSignal);                                            

    fprintf(stdout, "%d(%s) signal caught\n", sArrivedSignal, strsignal(sArrivedSignal));
}                                                                                        

Я не смог поймать сигнал, когда epoll_wait () прерывается.

Способ 2

Когда я выполняю свое приложение в инструменте strace, epoll_wait() никогда не прерывается.

Моя проблема очень хорошо воспроизводится в инструменте GDB. Мне нужна помощь....

2 ответа

Вы можете попробовать реализовать свой собственный обработчик сигналов. Если ваше приложение прервано сигналом снова, будет вызван ваш собственный обработчик сигнала, и вы сможете увидеть, какой сигнал был подан.

void
signal_callback_handler(int signum)
{
  printf("Caught signal %d\n",signum);
  exit(signum); // terminate application
}

int main()
{
  // Register signal handler for all signals you want to handle
  signal(SIGINT, signal_callback_handler);
  signal(SIGABRT, signal_callback_handler);
  signal(SIGSEGV, signal_callback_handler);
  // .. and even more, if you want to
}

Не очень удобный метод, но он (надеюсь) позволит вам выяснить, какой сигнал был поднят. Посмотрите здесь, чтобы увидеть различные сигналы, которые могут быть обработаны (примечание: не все сигналы могут быть обработаны в вашем собственном обработчике сигналов (!)).

Может быть, вам следует попробовать установить обработчик сигналов для перехвата всех сигналов и установить флаги сигналов на SA_SIGINFO

что-то вроде этого

struct sigaction act;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO;
act.sa_sigaction = <handler>;

sigaction(SIGFPE, &act, 0);
sigaction(SIGHUP, &act, 0);
sigaction(SIGABRT, &act, 0);
sigaction(SIGILL, &act, 0);
sigaction(SIGALRM, &act, 0);
sigaction(SIGALRM, &act, 0);
.
.
.

//and your handler looks like

void handle_sig (int sig, siginfo_t *info, void *ptr)
{
     printf ("Signal is %d\n",sig);
}

Зарегистрируйте обработчик в вашей основной программе и игнорируйте EINTR в epoll.

Другие вопросы по тегам