Почему бы не поймать сигналы? - PullRequest
4 голосов
/ 12 июля 2011

В самом начале моего main () у меня есть:

signal(SIGTERM, SIGTERM_handler);

SIGTERM_handler:

void SIGTERM_handler(int signum) {

    NSLog(@"Caught signal: [%d]. Cleaning up ...",signum);
    //cleanup();
    NSLog(@"Done cleaning up. Exiting ...");
    exit(EXIT_FAILURE);
}

Эти строки никогда не печатаются. Когда я устанавливаю точки останова в обработчике, они никогда не удаляются. Я нигде не звоню sigaction(). GDB настроен для прохождения через сигналы, которые меня интересуют (handle SIGTERM SIGINT pass stop print или handle SIGTERM SIGINT pass nostop print). Даже обработчик сигналов по умолчанию не работает - отправка SIGINT (для которого я не указал обработчик) программе также ничего не делает.

Что может быть причиной этого?

Ответы [ 4 ]

5 голосов
/ 12 июля 2011

Я не знаю Цель C, но у меня есть опыт работы с обработчиками сигналов, поэтому я отвечу так, как будто для POSIX и C.

Вызов любой функции, которая не задокументирована как "безопасная асинхронная передача сигналов"в обработчике сигналов есть риск и его следует избегать.Вы не можете делать какие-либо предположения о стеке или любом другом состоянии, когда вызывается обработчик сигнала.Стек может даже быть "уничтожен" (в процессе создания или уничтожения кадра), когда вызывается ваш обработчик сигнала.Ваши библиотеки могут иметь несовместимое состояние при вызове вашего обработчика сигнала.

Объявите флаг volatile (int), который проверяется в вашем цикле событий или что-то еще, чтобы увидеть, изменился ли он.Обработчик сигнала должен устанавливать ТОЛЬКО этот флаг и возвращать, больше ничего.(Если ваша платформа не передает сигналы в стиле SVR4, в этом случае вам также необходимо переустановить обработчик сигналов в обработчике сигналов.)

Сообщения журнала и другие действия в ответ на сигнал должны выполнятьсялюбой код проверяет флаг и обрабатывает событие, подразумеваемое флагом.

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

2 голосов
/ 21 ноября 2012

Шон, так что вы используете CZMQ, который перенаправляет сигналы для своих собственных целей всякий раз, когда вы делаете zctx_new (). Мой совет, если возможно, позволить CZMQ выполнить свою задачу и перехватить прерывание, используя предоставляемые им механизмы, которые являются глобальной переменной zctx_interrupted, а в любом блокирующем вызове ZMQ - нулевой возврат и код ошибки EINTR.

0 голосов
/ 12 июля 2011

Вы запускаете это в отладчике?Я столкнулся с проблемами, связанными с обработкой сигналов по-разному на платформе iOS внутри и за пределами запуска с GDB.Я думаю, что такая же проблема возникает в OSX.Прошло много времени, и я не могу дать вам подробности

0 голосов
/ 12 июля 2011

Оказывается, что-то связано с zsocket_new czmq.Переключение на zctx__socket_new исправило это.Я еще не покопался, чтобы точно узнать, что происходит.

...