У меня есть консольное приложение C ++, встроенное в XCode 6, и я хочу добавить обработчик SIGTERM к нему. Есть много примеров, но я не могу заставить их работать.
#include <csignal>
namespace
{
volatile std::sig_atomic_t gDone = 0;
}
static void term_handler(int i)
{
gDone = 1;
}
int main(int argc, const char * argv[])
{
std::signal(SIGTERM, term_handler);
while (!gDone);
return 0;
}
Отладчик остановился на while
заявление, но обработчик не был вызван. Та же проблема с этим кодом
#include <signal.h>
volatile sig_atomic_t gDone = 0;
void term_handler(int i)
{
gDone = 1;
}
int main(int argc, char* argv[])
{
struct sigaction sa;
sigset_t newset;
sigemptyset(&newset);
sigaddset(&newset, SIGHUP);
sigprocmask(SIG_BLOCK, &newset, 0);
sa.sa_handler = term_handler;
sigaction(SIGTERM, &sa, 0);
while(!gDone);
return 0;
}
Есть ли проблема с кодом? Как правильно обрабатывать сигналы в OSX?
Хорошо, я сейчас дома и работаю над своим Mac. Опять же, ваш код (в частности, второй пример) доказал свою эффективность. Подтверждение было сделано в Терминале с помощью gcc и «kill -TERM». Источник ссылается на SIGTERM, как обычно, но kill ссылается (на OS X) на TERM. Пауза XCode, которую вы видите, вызвана XCode, а не вашим кодом. Я пробовал оба способа, Терминал и XCode. Тем не менее, я не смог найти префа для подавления этого прерывания.
Просто чтобы сосредоточиться здесь … Вы спросили: есть ли проблема с кодом? Ответ: Нет. Вы спросили, как правильно обрабатывать сигналы в OSX? Ответ: То, как вы уже это делаете. Новый вопрос: как мне заставить XCode (lldb) не делать паузу при появлении сигналов? Ответ: Как сказать отладчику LLDB не обрабатывать SIGBUS?
После того, как вы отправите сигнал, и отладчик остановится, вы должны продолжить работу до точки останова внутри обработчика сигнала.
(lldb) break set -n term_handler Breakpoint 1: where = a.out`term_handler(int) + 4 at sig.cc:11, address = 0x0000000100000f54 (lldb) run Process 42532 launched: './a.out' (x86_64) Process 42532 stopped * thread #1: tid = 0x18dc39, 0x0000000100000f30 a.out`main(argc=15, argv=0x00007fff5fbffb58) + 32 at sig.cc:17, queue = 'com.apple.main-thread', stop reason = signal SIGTERM frame #0: 0x0000000100000f30 a.out`main(argc=15, argv=0x00007fff5fbffb58) + 32 at sig.cc:17 14 int main(int argc, const char * argv[]) 15 { 16 std::signal(SIGTERM, term_handler); -> 17 while (!gDone); 18 std::puts("done!"); 19 return 0; 20 } (lldb) c Process 42532 resuming Process 42532 stopped * thread #1: tid = 0x18dc39, 0x0000000100000f54 a.out`term_handler(i=15) + 4 at sig.cc:11, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x0000000100000f54 a.out`term_handler(i=15) + 4 at sig.cc:11 8 9 static void term_handler(int i) 10 { -> 11 gDone = 1; 12 } 13 14 int main(int argc, const char * argv[]) (lldb) `
Ваш код в порядке. Убить с помощью:
kill -SIGTERM 31573
так как
kill -9 31573
где 31573 был мой идентификатор процесса, не выходил изящно. Я добавил printf в ваш код, чтобы сказать мне, что он грациозно завершается.