При возврате si_addr со смещением от функции sigwaitinfo возникает ошибка сегментации - PullRequest
1 голос
/ 01 июня 2019

Я работаю над 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;
}

1 Ответ

1 голос
/ 05 июня 2019

Вы неправильно используете si_addr.Он доступен только для ограниченного числа сигналов, и они не включают в себя сигналы реального времени.

По POSIX , si_addr не применимо для сигналов, отличных от SIGILLSIGFPE, SIGSEGV и SIGBUS.Linux также предоставляет si_addr данные для SIGTRAP:

SIGILL, SIGFPE, SIGSEGV, SIGBUS и SIGTRAP для заполнения si_addr с адресомошибка.

Никакие другие сигналы не дают значения для si_addr.

Исходный код linux/kernel/signal.c, который заполняется si_addr, ясно показывает, чтоsi_addr не используется для каких-либо сигналов, кроме перечисленных.

Обратите внимание, что для справочной страницы Linux signal(7) :

Сигналы в реальном времениразличаются следующим:

  1. Несколько экземпляров сигналов реального времени могут быть поставлены в очередь.Напротив, если несколько экземпляров стандартного сигнала доставляются, когда этот сигнал в настоящий момент заблокирован, то только один экземпляр ставится в очередь.

  2. Если сигнал отправляется с использованием sigqueue(3), сопровождающее значение (целое число или указатель) может быть отправлено с сигналом.Если процесс приема устанавливает обработчик для этого сигнала, используя флаг SA_SIGINFO в sigaction(2), он может получить эти данные через поле si_value структуры siginfo_t, переданной в качестве второго аргумента.к обработчику.Кроме того, поля si_pid и si_uid этой структуры могут использоваться для получения PID и реального идентификатора пользователя процесса, отправляющего сигнал.

...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...