handling sigterm in OSx

2019-07-23 15:42发布

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?

3条回答
Rolldiameter
2楼-- · 2019-07-23 16:19

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) `
查看更多
欢心
3楼-- · 2019-07-23 16:21

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.

查看更多
对你真心纯属浪费
4楼-- · 2019-07-23 16:24

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?

查看更多
登录 后发表回答