我正在研究signal handler来处理reap信号,当我调用sigwaitinfo函数时,随机得到带偏移量的信号。所有的信号属性都是正确的,除了info.si_addrinfo.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;
}

最佳答案

你误用了si_addr。它只适用于有限数量的信号,而那些信号不包括任何实时信号。
Per POSIXsi_addr不适用于SIGILLSIGFPESIGSEGVSIGBUS以外的信号。Linux还为si_addr提供SIGTRAP数据:
SIGILLSIGFPESIGSEGVSIGBUSSIGTRAP填写故障地址。
没有其他信号提供si_addr的值。
The source code si_addr中填写的linux/kernel/signal.c清楚地表明si_addr不用于所列信号以外的任何信号。
请注意,perthe Linux si_addr man page
实时信号的区别如下:
实时信号的多个实例可以排队。由
对比度,如果一个标准信号的多个实例
在该信号当前被阻止时发送,则只有一个
实例已排队。
如果使用signal(7)发送信号,则伴随值
(整数或指针)可以随信号一起发送。如果
接收过程使用
sigqueue(3)标志设置为SA_SIGINFO,则可以获取此数据
通过sigaction(2)结构的si_value字段
处理程序的第二个参数。此外,siginfo_t
si_pid此结构的字段可用于获取PID和
发送信号的进程的实际用户ID。

07-28 01:33
查看更多