而 return si_addr 与 sigwaitinfo 函数的偏移导致分段错误

While return si_addr with offset from sigwaitinfo function causing segmentation fault

我正在研究 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;
}

您在滥用 si_addr。它仅适用于有限数量的信号,并且不包括任何 real-time 信号。

Per POSIXsi_addr不适用于SIGILLSIGFPESIGSEGVSIGBUS以外的信号。 Linux 还为 SIGTRAP:

提供 si_addr 数据

SIGILL, SIGFPE, SIGSEGV, SIGBUS, and SIGTRAP fill in si_addr with the address of the fault.

没有其他信号提供 si_addr 的值。

填写si_addr

The source code linux/kernel/signal.c清楚地表明si_addr不用于列出的信号以外的任何信号。

请注意,根据 the Linux signal(7) man page:

Real-time signals are distinguished by the following:

  1. Multiple instances of real-time signals can be queued. By contrast, if multiple instances of a standard signal are delivered while that signal is currently blocked, then only one instance is queued.

  2. If the signal is sent using sigqueue(3), an accompanying value (either an integer or a pointer) can be sent with the signal. If the receiving process establishes a handler for this signal using the SA_SIGINFO flag to sigaction(2), then it can obtain this data via the si_value field of the siginfo_t structure passed as the second argument to the handler. Furthermore, the si_pid and si_uid fields of this structure can be used to obtain the PID and real user ID of the process sending the signal.

...