在C中安装信号处理程序

时间:2014-01-17 08:09:59

标签: c signals signal-processing interrupt

我正试图从我的程序中捕获SIGSEGV。我遇到了一个问题,我的signal_handler没有捕获到信号。

void handler(int sig){
  printf("catch SIGSEGV");
  exit(EXIT_FAILURE);
}


void foo(){
   struct sigaction sa;
   sa.sa_flags = SA_SIGINFO;
   sigemptyset(&sa.sa_mask);
   sa.sa_handler = handler;
   if(sigaction(SIGSEGV, &sa, NULL) == -1){
       handle_error("sigaction");
   }
   /* if SIGSEGV happen here, I can catch it */
   bar();
}

void bar() {
     /* if SIGSEGV happen here, I cannot catch it */
}

这是否意味着我必须在栏内安装另一个信号处理程序?

但是如果我有一堆想要捕获相同信号的函数怎么办呢。我必须多次安装信号处理程序?

更新:

我试图直接在函数中安装处理程序但仍然无法捕获它。所以我认为这可能是其他问题。但那很奇怪。我使用gdb来运行并获取

Program received signal SIGSEGV, Segmentation fault.
0x080499b1 in is_printable_string (
    str=0xb80fe768 <Address 0xb80fe768 out of bounds>)
    at trace/trace.c:259
259   while(str[index]!='\0'){

这是我的is_printable_String

int is_printable_string(char *str){
 struct sigaction sa;
  sa.sa_flags = SA_SIGINFO;
  sigemptyset(&sa.sa_mask);
  sa.sa_sigaction = handler;
  if(sigaction(SIGSEGV, &sa, NULL) == -1){
    handle_error("sigaction");
  }
  int index;
  index=0;
  while(str[index]!='\0'){
     if(!isprint(str[index])){
          return -1;
      }
  index++;
  }
  /* continue... */

这似乎我得到了一个SEG故障,但我无法抓住它

我故意传递了那个指针,所以str参数没有错。

2 个答案:

答案 0 :(得分:1)

来自sigaction ...

的手册页
  

SA_SIGINFO(自Linux 2.2起)信号处理程序采用三个参数,   不是一个。在这种情况下,应该设置sa_sigaction而不是   sa_handler。该标志仅在建立信号时有意义   处理程序。

因此,您的问题应该是

sa.sa_flags = SA_SIGINFO;

将其更改为

sa.sa_flags = 0;

看看它是怎么回事。

答案 1 :(得分:1)

确实,因为ajcaruana指出你的处理程序与SA_SIGINFO不匹配。但是,如果您正在捕捉SIGSEGV,您可能需要SA_SIGINFO,以查看有问题的地址和内容。在这种情况下,您的信号处理程序需要如下所示:

static void
handler(int sig, siginfo_t *si, void *ucontext)
{
    /* ... */
}

特别是,您可能对si_addr

感兴趣
  

对于SIGBUS和SIGSEGV信号,该字段包含地址   导致无效的内存引用。