如果一个进程运行kill(-1,SIGKILL);
(或使用不同的信号)并且该调用杀死调用者(MacOS的kill(-1,...)
执行此操作,虽然Linux让调用者保持活动状态)但不是其父代(父代有不同的uid),父母可以使用设施由POSIX提供,告诉kill-caller是否因为使用kill(-1,...)
调用自杀而死,或者是因为另一个进程杀了它?
首先,如果你将SIGKILL
发送到进程,它们将永远不会看到信号 - 它们只是被内核立即杀死。
否则,根据2.4.3 Signal Actions of the POSIX standard,如果信号处理程序使用SA_SIGINFO
标志注册,则可以提取发送信号的进程的PID:
如果设置了信号的
SA_SIGINFO
标志,则信号捕获功能应作为C语言函数调用输入,如下所示:void func(int signo, siginfo_t *info, void *context);
其中
func
是指定的信号捕获函数,signo
是传递信号的信号编号,info
是指向siginfo_t
中定义的<signal.h>
结构的指针,该结构至少包含以下成员:Member Type Member Name Description int si_signo Signal number. int si_code Cause of the signal. pid_t si_pid Sending process ID. uid_t si_uid Real user ID of sending process. void * si_addr Address of faulting instruction. int si_status Exit value or signal. union sigval si_value Signal value.
si_signo
成员应包含信号编号。这应与signo
参数相同。si_code
成员应包含识别信号原因的代码。为si_code
定义了以下非信号特定值:
SI_USER
信号由kill()
函数发送。如果信号是由si_code
或SI_USER
函数或作为实现扩展提供的任何类似函数发送的,则实现可以将raise()
设置为abort()
。SI_QUEUE
信号由sigqueue()
函数发送。SI_TIMER
信号是由timer_settime()
设定的计时器到期产生的。SI_ASYNCIO
信号是由完成异步I / O请求生成的。SI_MESGQ
信号是通过消息到达空消息队列而生成的。如
si_code
中所述,还定义了<signal.h>
的信号特定值。
这应该提供足够的信息来判断信号是否是通过调用kill()
产生的,什么过程发送信号,谁发送了信号。或者,如果信号是由内部故障产生的,例如使用SIGSEGV
。