【问题标题】:signal handler returns segmentation fault:11信号处理程序返回分段错误:11
【发布时间】:2014-03-18 07:37:15
【问题描述】:

我已经注册了一个打印信号编号的处理程序,然后将原始函数调用到SIGINT

#include <stdio.h>
#include <signal.h>

void (*orifunc)(int);

void func(int sig) {
    printf("signal number is %d. \n", sig);
    orifunc(sig);
    return;
}

int main() {
    orifunc = signal(SIGINT, func);
    while (1);
    return 0;
}

但是当我运行时,在执行printf 之后,它返回了“分段错误:11”。 为什么会这样?

因为SIG_DFL 不是一个真正的函数。我尝试这样编写代码:

#include <stdio.h>
#include <signal.h>

void func(int sig) {
    printf("signal number is %d. \n", sig);

    signal(SIGINT, SIG_DFL);
    raise(sig);
    signal(SIGINT, func);
    return;
}

int main() {
    signal(SIGINT, func);
    while (1);
    return 0;
}

然后它运行func递归并在整个屏幕上打印字符串。 如何正确运行我的处理程序中的默认处理程序?

【问题讨论】:

  • orifunc()的值是多少?
  • 我认为它会是 'SIG_DFL'。

标签: c unix signals


【解决方案1】:

在调用orifunc() 之前,您需要检查它是否是特殊处理程序值之一,因为这些不是真正的函数。所以你需要这样做:

if(orifunc != SIG_DFL && orifunc != SIG_IGN && orifunc != SIG_HOLD) {
    orifunc(sig);
}

或者你可以把原来的handler放回去重新发给自己:

void func(int sig) {
    printf("signal number is %d. \n", sig);
    signal(sig, orifunc);
    raise(sig);
}

【讨论】:

  • 是的,它是 SIG_DFL。但是我希望函数在 printf 之后像默认值一样杀死自己。我该怎么办?
  • SIG_DFL 不是默认运行的真正功能吗?
  • 查看sys/signal.h:#define SIG_DFL (void (*)(int))0
  • 你能做的就是把原来的信号处理器放回去,然后再把信号发给自己。
  • 谢谢,我试过了。如果没有signal(SIGINT, func);,则运行正常。但是为什么加了这段代码之后就出错了呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-10
  • 2012-01-08
  • 2011-09-16
  • 1970-01-01
相关资源
最近更新 更多