2

我在 XCode 6 中构建了控制台 C++ 应用程序,并希望向其添加 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 中处理信号的正确方法是什么?

4

3 回答 3

2

发送信号后,调试器停止,您必须继续到达信号处理程序内的断点。

(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) `
于 2015-05-28T21:25:51.653 回答
1

你的代码很好。杀死:

kill -SIGTERM 31573

因为

kill -9 31573

其中 31573 是我的进程 ID,没有正常退出。我在你的代码中添加了一个 printf 来告诉我它正在优雅地退出。

于 2015-05-28T20:41:56.957 回答
1

好的,我现在在家,正在使用我的 Mac。同样,您的代码(特别是第二个示例)已被证明很好。确认是在终端中使用 gcc 和“kill -TERM”完成的。Source 指的是 SIGTERM,就像正常的一样,但 kill 指的是(在 OS X 上)TERM。您看到的 XCode 暂停是由于 XCode 而不是您的代码。我尝试了两种方式,终端和 XCode。然而,我找不到抑制这种中断的偏好。

只是集中在这里......你问,代码有问题吗?答:不。您问,在 OSX 中处理信号的正确方法是什么?答:你已经这样做了。新问题:如何让 XCode (lldb) 在信号发生时不暂停?答:如何告诉 LLDB 调试器不要处理 SIGBUS?

于 2015-05-29T14:15:14.483 回答