首页 > 解决方案 > 虽然返回 si_addr 与 sigwaitinfo 函数的偏移量导致分段错误

问题描述

我正在signal handler处理收割信号,随机我在调用sigwaitinfo函数时得到带有偏移的信号。所有信号属性都是正确的,除了info.si_addr. 这个偏移量info.si_addr导致了分段错误。

这个偏移量似乎是相同的 - 我已经尝试删除偏移量并且有效,但我需要一个正确的解决方案才能继续前进。

static void *signalHandler(void *vptr_args __attribute__((unused)))
  {
      sigset_t signal_set;
      siginfo_t info;

      sigemptyset(&signal_set);
      sigaddset(&signal_set, SIG_REAP);
      sigaddset(&signal_set, SIG_ISOC_CANCEL);
      sigaddset(&signal_set, SIGTERM);
      sigaddset(&signal_set, SIGPIPE);

      while (true) {
          int rc = sigwaitinfo(&signal_set, &info);
          //...
          if (rc > 0) 
{
            if(info.si_signo == SIG_REAP) 
               {
                 // Reap URBs after some simple checks
                 if ((info.si_code != SI_ASYNCIO) &&
                     (info.si_code != SI_KERNEL)) {
                      printf("Bad si_code %d in SIG_REAP", info.si_code);                      
                      continue;
                 } 
                   else {
                      printf("OK si_code %d in SIG_REAP", info.si_code);
                 }
                   struct usbdevfs_urb *ioctl_urb = (struct usbdevfs_urb*)info.si_addres
                  if (!ioctl_urb) {
                     printf("SIG_REAP gave NULL ioctl_urb");
                      continue;
                  }
                  UrbInfo *urbInfo = ioctl_urb->usercontext;
                  if (!urbInfo) {
                     printf("SIG_REAP gave NULL urbInfo");
                      continue;
}

标签: clinuxmultithreadinglinux-kernelsignals

解决方案


你在滥用si_addr. 它仅适用于有限数量的信号,并且不包括任何实时信号。

根据 POSIXsi_addr不适用于SIGILLSIGFPESIGSEGV和以外的信号SIGBUS。Linux 还提供si_addr以下数据SIGTRAP

SIGILL, SIGFPE, SIGSEGV, SIGBUS,SIGTRAP填写si_addr故障地址。

没有其他信号为 提供值si_addr

linux/kernel/signal.c填写的源代码si_addr清楚地表明,si_addr除了列出的信号外,不用于任何信号。

请注意,根据Linuxsignal(7)手册页

实时信号的区别如下:

  1. 实时信号的多个实例可以排队。相反,如果一个标准信号的多个实例被传递而该信号当前被阻塞,那么只有一个实例被排队。

  2. 如果使用 发送信号sigqueue(3),则可以随信号发送一个伴随值(整数或指针)。SA_SIGINFO如果接收进程使用to 标志为这个信号建立一个处理程序,那么它可以通过作为第二个参数传递给处理程序的结构的字段sigaction(2)获取这个数据。此外,该结构体的and 字段可用于获取发送信号的进程的 PID 和真实用户 ID。si_valuesiginfo_tsi_pidsi_uid

...


推荐阅读