【发布时间】:2021-04-26 13:17:53
【问题描述】:
spec 这么说
如果在 sa_flags 中指定了 SA_SIGINFO,则 sa_sigaction (而不是 sa_handler)指定信号处理函数 签名。
但是,下面的代码可以神奇地工作
#include <stdio.h>
#include <signal.h>
static void handler(int signo, siginfo_t *si, void *uc){
printf("si = %d\n", *(char*)si);
printf("uc = %d\n", *(char*)uc);
}
int main(void)
{
struct sigaction psa;
psa.sa_flags = 0;
psa.sa_sigaction = handler;
sigaction(SIGTSTP, &psa, NULL);
for(;;) {}
return 0;
}
handler 能够访问 si 和 ui 处的内存,gdb 显示至少 si 确实是指向 siginfo_t 的指针。但是,code 将 sa_sigaction 和 sa_handler 实现为联合。如果运行时使用 sa_flags 来决定使用 sa_sigaction 还是 sa_handler,似乎很难知道应该使用 sa_sigaction...
这是否意味着运行时总是为这两种调用提供 si 和 uc ?这样的用户代码是否定义明确?
【问题讨论】:
-
不管[它正在做什么,根据您的测试结果],传递额外参数的代码更少。它不会“伤害”
sa_handler[你总是可以传递比签名指定更多的参数,第一个参数是int] 这有点争议。您的代码正在设置 wrong 结构成员,并且由于联合而“逍遥法外”。如果你真的需要知道,请拉 [linux] 内核源代码并追踪设置它的代码。这是 linux,但在另一个 posix sys 上,这可能不起作用(即不是联合)。 -
它没有说明如果代码不这样做会是什么行为。所以这是一个经典的未定义行为。如果您编写这样的代码,请准备好在某些时候中断。
-
顺便说一句,
printf->malloc-> 不是信号安全