waitpid()之后来自WTERMSIG宏的异常信号编号

时间:2013-09-30 18:37:20

标签: c++ macos signals bsd waitpid

在等待子进程终止时,我从以下代码中看到异常的信号编号(例如50,80或117)。我只是从一个特定的子进程看到这个,并且我无法访问进程源代码,它只在某些时候发生。

我想知道这些不寻常的值是什么意思,给定NSIG == 32,我可以在标题或手册页中找到一些文档?

请注意,此代码在循环中运行,逐渐发送更多威胁信号,直到子项终止。

int status, signal;

if (waitpid(m_procId, &status, WNOHANG) < 0) {
    LOGERR << "Failed to wait for process " << name() << ": " <<
        strerror(errno) << " (" << errno << ")";
    break;
} else if (WIFEXITED(status)) {
    m_exitCode = WEXITSTATUS(status);
    terminated = true;
    LOGINF << "Process " << name() << " terminated with exit code " << m_exitCode;
} else if (WIFSIGNALED(status)) {
    signal = WTERMSIG(status);    // !!! signal is sometimes 50, 80 or 117 !!!
    terminated = true;
    LOGINF << "Process " << name() << " terminated by signal " << signal;
} else {
    LOGWRN << "Process " << name() << " changed state but did not terminate.  status=0x" <<
        hex << status;
}

这是在OSX 10.8.4下运行的,但我也在10.9 GM种子中看到了它。

编辑修改下面的代码会使代码更加健壮,但有时子进程会变成孤立状态,因为我猜循环不足以杀死子进程。

else if (WIFSIGNALED(status)) {
    signal = WTERMSIG(status);
    if (signal < NSIG) {
        terminated = true;
        LOGINF << "Process " << name() << " terminated by signal " << signal;
    } else {
        LOGWRN << "Process " << name() << " produced unusual signal " << signal
               << "; assuming it's not terminated";
    }
}

请注意,此代码是此classProcess::unload()方法的一部分。

1 个答案:

答案 0 :(得分:2)

OS X manpage for waitpid开始,在指定WNOHANG时,你应该检查0的返回值:

 When the WNOHANG option is specified and no processes wish to report status, wait4() returns a process
 id of 0.

 The waitpid() call is identical to wait4() with an rusage value of zero.  The older wait3() call is the
 same as wait4() with a pid value of -1.

发布的代码没有检查这一点,这告诉我status的值可能是垃圾(int的值永远不会被初始化)。这可能会导致你所看到的。

编辑:status确实仅在waitpid返回&gt;时设置0.