I have console C++ application built in XCode 6 and want to add SIGTERM handler to it. There are a lot of examples, but I can't get them to work.
#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;
}
The debugger stopped on the while
statement, but the handler was not called. The same problem with this code
#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;
}
Is there a problem with the code? What is the right way to handle signals in OSX?
OK, I'm home now and working on my Mac. Again, your code (second sample specifically) has proven just fine. The confirmation was done in Terminal with gcc and "kill -TERM ". Source refers to SIGTERM, like normal, but kill refers (on OS X) to TERM. The XCode pause you are seeing is due to XCode, not your code. I tried it both ways, Terminal and XCode. I could not find a pref to inhibit that interruption, however.
Just to focus here ...You asked, Is there a problem with the code? Answer: No. You asked, What is the right way to handle signals in OSX? Answer: The way you're already doing it. New question: How do I get XCode (lldb) to not pause when signals occur? Answer: How to tell LLDB debugger not to handle SIGBUS?
After you send the signal, and the debugger stops, you have to continue to get to your breakpoint inside the signal handler.
(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) `
Your code is fine. Kill with:
kill -SIGTERM 31573
because
kill -9 31573
where 31573 was my process ID, did not exit gracefully. I added a printf to your code to tell me it was exiting gracefully.