Signal 将回调函数作为其参数之一。要具有可变行为,我想在函数内创建一个函数。到目前为止,这是我的尝试:
typedef void (*sighandler_t)(int);
sighandler_t f(int pid) {
void sigintHandler(int sig) {
printf("Process %d", pid);
}
return sigintHandler
}
int main(void) {
...
if (signal(SIGTSTP, *f(1)) == SIG_ERR) {
...
}
...
}
但是,每次我发送 SIGTSTP (Ctrl-z) 时,我都会遇到段错误。
作为旁注:任何关于如何调试一般段错误的提示都将不胜感激!
最佳答案
您的代码可以编译,因为它在语法上是正确的,并且您正在使用编译器扩展;但是,您的代码存在一些基本问题,可能会导致您的段错误
。
首先,您的信号处理程序代码:
typedef void (*sighandler_t)(int);
sighandler_t f(int pid) {
void sigintHandler(int sig) {
printf("Process %d", pid);
}
return sigintHandler;
}
这是 not standard C甚至需要 -ftrampolines
在某些版本的 gcc
上指定标志以实际编译。
您的信号处理函数本身有一些问题需要解决:
sigintHandler
是一个 nested function ,因此当您的信号处理函数 f
通过 return sigintHandler;
返回时,您将返回一个函数指针。
在您的代码中,这可以正确编译,因为您有 typedef void (*sighandler_t)(int);
,它定义了一个函数指针类型,可以指向具有 void< 的函数
返回类型并将 int
作为参数,您的 sigintHandler
被定义为。
相反,您的信号处理函数可以简单地写成:
void sigintHandler(int sig) {
printf("Signal %d\n", sig);
}
在你的主要功能中,你有以下内容:
if (signal(SIGTSTP, *f(1)) == SIG_ERR) {
// ....
}
这里需要注意的是,这也存在一些问题。首先,signal
函数的第一个参数是信号编号(通常是在 signal.h
header 中定义的宏),第二个参数是指向定义为 void func_name(int sig)
的函数的指针。
为此,您调用函数而不是将其作为指针传递。
*f(1)
实际上调用了 f
并将 1
作为其参数;相反,您可以将其更改为以下内容:
if (signal(SIGTSTP, f) == SIG_ERR) {
// ....
}
但这应该发出警告/错误,因为 f
被定义为返回函数指针而不是 void
。
因此,要更改代码以使其合规,您只需执行以下操作:
#include <stdio.h>
#include <signal.h>
void sigintHandler(int sig) {
printf("Signal %d", sig);
}
int main(void) {
// ...
if (signal(SIGTSTP, sigintHandler) == SIG_ERR) {
// ...
}
// ...
return 0;
}
但是你说:
To have variable behaviour ...
这取决于您想要的变量性质,但如果它是基于信号的变量函数,您可以执行以下操作:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void sig_stop(int sig) {
printf("Process %d stop\n", getpid());
}
void sig_int(int sig) {
printf("Process %d interrupt\n", getpid());
}
int main(void) {
// ...
if (signal(SIGTSTP, sig_stop) == SIG_ERR) {
// ...
}
if (signal(SIGINT, sig_int) == SIG_ERR) {
// ...
}
// ...
return 0;
}
或者您可以使用 switch
语句:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void sigHandler(int sig) {
printf("Process %d received %d\n", getpid(), sig);
switch (sig) {
case SIGTSTP:
// do stop code
break;
case SIGINT:
// do interupt code
break;
}
}
int main(void) {
// ...
if (signal(SIGTSTP, sigHandler) == SIG_ERR) {
// ...
}
if (signal(SIGINT, sigHandler) == SIG_ERR) {
// ...
}
// ...
return 0;
}
any tips on how to debug seg faults in general would be really appreciated!
首先,了解什么是segmentation fault是;然后你可以使用像gdb
这样的调试器单步执行您的代码或检查故障转储以查看发生段错误
的具体位置。
希望对您有所帮助。
关于C - 高阶函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41771552/