C语言 如何检查进程是忽略还是处理信号?



使用signal()或者最好是sigaction(),我们可以选择忽略或显式处理大多数POSIX信号。例如,为了忽略SIGCHLD我们可以执行以下操作:

struct sigaction sa_chld = { .sa_handler = SIG_IGN };
sigaction(SIGCHLD, &sa_chld, NULL);

有没有办法弄清楚给定的信号是否被程序忽略和/或捕获?

理想情况下,我想区分信号是否...

  • 正在按照默认操作进行处理
  • 被显式忽略
  • 被显式捕获

对于正在运行的进程,您可以签出/proc/PID/status并分别检查字段SigBlkSigIgnSigCgt是否有阻塞、忽略和捕获的信号。

有人编写了一个方便"解码"它的实用程序脚本,我个人认为它非常有用并一直在使用它。

有关详细信息和更多相关字段,请参阅proc文档。

是的。

例:

#include <signal.h>
#include <stdio.h>
void h(int Sig){(void)Sig; }
int main()
{
signal(1,SIG_IGN); //note: setting ign/dfl is more compat (and still safe) with signal()
sigaction(2, &(struct sigaction){.sa_handler=h},0);
for(int i=1; i<8; i++){
struct sigaction oldsa;
sigaction(i, 0, &oldsa);
if(!(oldsa.sa_flags&SA_SIGINFO)){
if(oldsa.sa_handler==SIG_IGN) printf("%d ignoredn", i);
else if(oldsa.sa_handler==SIG_DFL) printf("%d defaultedn", i);
else goto caught;
}else caught:
printf("%d caughtn", i);
}
}

示例输出:

1 ignored
2 caught
3 defaulted
4 defaulted
5 defaulted
6 defaulted
7 defaulted

在 Linux 上不可移植,您还可以解析/proc/$PID/stat(或具有人类可读版本的status(以查看信号是否在进程的捕获/忽略掩码中 (if(mask&(1ul<<(signalnumber-1)) printf("%d in the mask", signalnumber);(。

Linux 将捕获/忽略的信号列表作为位掩码维护,但 POSIX 不会公开这些信号,而是要求您通过对sigaction的非设置调用单独获取每个单独的处置。

最新更新