gpt4 book ai didi

linux - 通过 CTRL-C 接收 SIGINT 时发送者 pid 为零

转载 作者:太空狗 更新时间:2023-10-29 12:13:02 24 4
gpt4 key购买 nike

在我的信号处理程序中,它是通过 sigaction() 使用 SA_SIGINFO 标志设置的 si_pid 成员(它存储发送进程 ID)当通过 CTRL-C

触发 SIGINT 时, siginfo_t 结构的值为零

以下示例使用 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 killtkilltgkill 的系统调用跟踪器 我可以验证信号是由 sys_kill 在第一个示例和最后一个示例中的 sys_tgkill

但是,当按下 CTRL-C 时,这些系统调用都不会被调用。

问题:按下 CTRL-C 时调用哪个(如果有的话)系统调用?谁将指令指针传递给 CTRL-C 上的系统调用处理程序?为什么 siginfo_t 结构中的发件人 pid 在 CTRL-C 上为零(错误或记录的功能)?

最佳答案

SIGINT 由于 CTRL-C 被按下而发送时,任何进程都不会调用系统调用。这就是发送方的 PID 为零的原因。

信号从内核发出。具体来说,TTY 模块。每个进程都(可选地)绑定(bind)到一个终端,即“控制终端”。每个终端都有一个定义的键序列,它为绑定(bind)到终端的所有进程生成一个 SIGINT。默认的键序列当然是 CTRL-C

在这种情况下,您可以将 PID 0 视为“内核进程”。

引用:

看看你是否能在 stty 的输出中发现 CTRL-C:

$ stty -a
speed 38400 baud; rows 24; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?;
swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc ixany imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke -extproc
  • 另请参阅 setpgid(2) 的“注释”部分有关控制终端的更多信息的手册页。

关于linux - 通过 CTRL-C 接收 SIGINT 时发送者 pid 为零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35154699/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com