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

Мое приложение имеет две темы. Каждый поток получает некоторые данные с сервера через каждый сокет. Потоки ждут возврата 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. Мне нужна помощь ….

1

Решение

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

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
}

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

1

Другие решения

Может быть, вам следует попробовать установить обработчик сигналов для перехвата всех сигналов и установить флаги сигналов на 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.

0

По вопросам рекламы [email protected]