我正在尝试编写一个信号处理程序,它需要知道发送信号的进程的 pid。siginfo_t
在带有 Xcode 10 的 macOS 10.14 上,我无法从传递给我的处理程序中获得任何有用的东西。
我已将我的代码简化为以下最小示例来演示该问题。在这个示例中,我生成了一个子进程来发送我想要测试的信号,该信号默认为SIGTERM
,但我尝试过的其他信号都没有更好的效果。
假设您想在 Mac 上构建和测试它,您可能想告诉 lldb 在收到信号时不要停止。您可以使用此 lldb 命令:pro hand -p true -s false SIGTERM
.
我也在用 C++ 编译,但我相信我已经删除了所有这些,示例代码现在应该是纯 C。
请注意,信号是否来自子进程、终端或其他进程并不重要,结果始终si_pid
为 0(以及除si_signo
and之外的所有内容si_addr
)。我发送信号多少次都没关系,所以它似乎不仅仅是一个竞争条件。
如何获取在 macOS 10.14 上发送信号的进程的 pid?我不记得在 10.12 上遇到过这个问题,这是我之前使用的。
这只是演示问题的示例,因此请忽略实际上不会导致问题的任何内容。
如果代码看起来应该像我预期的那样工作,那么我有兴趣查看关于它也可以工作的系统的评论。
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
volatile sig_atomic_t histogram[3] = {0,0,0};
volatile sig_atomic_t signaled = 0;
const int testsig = SIGTERM;
void sigaction_handler(int sig, siginfo_t* info, void* context)
{
switch (info->si_pid) {
case 0:
case 1:
histogram[info->si_pid]++;
break;
default:
histogram[2]++;
break;
}
signaled = 1;
}
int main(int argc, const char * argv[]) {
pid_t mainpid = getpid();
pid_t pid = fork();
if (pid == 0) {
while (kill(mainpid, 0) == 0) {
sleep(1);
kill(mainpid, testsig);
}
_exit(0);
}
struct sigaction sigAction;
memset( &sigAction, 0, sizeof( sigAction ) );
sigAction.sa_sigaction = sigaction_handler;
sigemptyset (&sigAction.sa_mask);
sigAction.sa_flags = SA_SIGINFO;
sigaction(testsig, &sigAction, NULL);
while (1) {
if (signaled) {
printf("pid 0: %d, pid 1: %d, others: %d\n", histogram[0], histogram[1], histogram[2]);
signaled = 0;
}
sleep(1);
}
}