在我的信号处理程序中,通过使用带有
现在,如果您在启动程序后按
如果我在程序中引发SIGINT(通过取消代码示例中的
现在,如果我启用了Linux的ftrace系统调用跟踪器,对于
SA_SIGINFO
标志的sigaction()
设置的方式,当通过CTRL-C
触发SIGINT
时,siginfo_t
结构体的si_pid
成员(存储发送进程的ID)为零。以下是使用signalfd()
演示此“问题”的简单示例:#include <sys/signalfd.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(void) {
sigset_t mask;
int sfd;
struct signalfd_siginfo fdsi;
ssize_t s;
printf("my process id: %d\n", getpid());
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
/* block signals to avoid default handling */
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
perror("sigprocmask");
return 1;
}
sfd = signalfd(-1, &mask, 0);
if (sfd == -1) {
perror("signalfd");
return 1;
}
printf("waiting for sigint ...\n");
/* raise(SIGINT); */
s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
if (s != sizeof(struct signalfd_siginfo)) {
perror("reading from signal fd");
return 1;
}
if (fdsi.ssi_signo != SIGINT) {
fprintf(stderr, "received unexpected signal %d\n", fdsi.ssi_signo);
return 1;
}
printf("received SIGINT from process %d\n", fdsi.ssi_pid);
return 0;
}
如果您运行此程序并从另一个tty触发kill -INT pid
,则程序的输出为:
my process id: 23540
waiting for sigint ...
received SIGINT from process 23186
现在,如果您在启动程序后按
CTRL-C
,输出结果是:my process id: 23551
waiting for sigint ...
^Creceived SIGINT from process 0
如果我在程序中引发SIGINT(通过取消代码示例中的
/* raise(SIGINT); */
行的注释),则输出结果为:my process id: 23577
waiting for sigint ...
received SIGINT from process 23577
现在,如果我启用了Linux的ftrace系统调用跟踪器,对于
kill
、tkill
和tgkill
,我可以验证信号是由第一个示例中的sys_kill
处理的,而由最后一个示例中的sys_tgkill
处理的。
然而,在按下CTRL-C
时,没有任何这些系统调用被调用。
问题:
在按下CTRL-C
时,哪个(如果有)系统调用被调用?
谁将指令指针传递给CTRL-C
上的系统调用处理程序?
为什么siginfo_t
结构中的发送方pid在CTRL-C
上为零(bug或文档化的特性)?