Signal SIGSEGV使用sigaction捕获

时间:2017-09-28 22:41:10

标签: linux signals handler sigsegv sigaction

我正在开发一个在linux pc内核版本4.4.14上运行的多线程应用程序。我想跟踪一些导致分段错误的灾难性错误。 我设置了一个链接到SIGSEGV的信号处理程序,试图获取导致崩溃的线程的pid号。处理程序功能代码如下:

void sighandler(int signum, siginfo_t *siginfo, void *context)  
{
    // get pid of sender,
  pid_t sender_pid = siginfo->si_pid;
  printf("Process %d got signal %d SEG FAULT !!!\n", (int)sender_pid, signum);
  fflush(stdout);
  sleep(1);
  printf("Stdout Flushed %d got signal %d SEG FAULT !!!\n", sender_pid, signum);
  trappola.sa_flags = 0;
    trappola.sa_handler = SIG_DFL;
    sigaction(signum, &trappola, NULL);
  kill(getpid(), signum);
  exit(-1);
}

并在main()中使用:

链接sighandler函数
struct sigaction trappola;  
memset(&trappola, 0x00, sizeof(trappola));

trappola.sa_flags = SA_SIGINFO;
trappola.sa_sigaction = sighandler;
sigaction(SIGSEGV, &trappola, NULL);

处理程序正在运行,但我无法获取导致错误的线程的pid。 printf:

printf("Process %d got signal %d SEG FAULT !!!\n", (int)sender_pid, signum);

总是打印不同的数字作为sender_pid,其中没有一个是有意义的。 为什么我无法得到违规线索的pid?

我哪里错了?如何在处理函数中获取有问题的线程的pid?

非常感谢您的帮助。

问候。

Marco Bisio

1 个答案:

答案 0 :(得分:0)

siginfo->si_pid没有意义,因为导致SIGSEGV的线程(在地址siginfo->si_addr)与接收信号的线程相同。

请参阅the signal(7) manpage

  

可以为整个过程生成(并因此待决)信号   (例如,使用kill(2)发送时)或特定线程(例如,   某些信号,如SIGSEGV和SIGFPE,生成为   执行特定机器语言指令的结果   是线索导向的(...)