Bug 20263 - setitimer fails to trigger in subthread if SIGALRM blocked
setitimer fails to trigger in subthread if SIGALRM blocked
Status: CLOSED CURRENTRELEASE
Product: Red Hat Linux
Classification: Retired
Component: glibc (Show other bugs)
8.0
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
Brian Brock
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2000-11-02 19:09 EST by Jonathan Larmour
Modified: 2016-11-24 10:05 EST (History)
1 user (show)

See Also:
Fixed In Version: 2.3.2-27.9
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2003-04-21 21:15:57 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Jonathan Larmour 2000-11-02 19:09:27 EST
This is a (potential!) bug report for RH7 with Linux 2.2.16-22enterprise on
an SMP machine, and with the glibc-2.1.94-3 errata RPM if that's any help.

Compile the below source with gcc -g -pthread -o foo2 foo2.c

You will not get any SIGALRMs generated. Out of interest, if you explicitly
do a "kill -ALRM" on the appropriate PID from another shell, the SIGALRM
*is* received. That would seem to imply it is a problem with generation not
reception, but the signal is marked as pending so it seems to be a problem
with the mask being set for every thread or something. glibc uses setitimer
to generate alarms unsurprisingly BTW.

If you change the #if 1 to a 0, then it works. This seems to imply that
setting the sigmask *after* the child has been created affected the child
thread anyway. Even though the child explicitly sets an empty signal mask
as well.

Jifl

#include <stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <signal.h>
#include <semaphore.h>

static sem_t sigalrm_sem;

static void sigalrm(int signo)
{
  printf("Alarm handler caught SIGALRM!\n");
  sem_post(&sigalrm_sem);
  return;
}

static void *alarm_hdlr_pthread(void *dummy)
{
  sigset_t s;
  sigemptyset(&s);
  pthread_sigmask(SIG_SETMASK, &s, NULL);
  printf("Alarm thread running!\n");
  for (;;)
  {
    sem_wait(&sigalrm_sem);
    printf("Alarm thread caught SIGALRM!\n");
  }
}

int main(void)
{
  sigset_t sigs_to_block;
  pthread_attr_t pattr;
  struct sigaction sa;
  pthread_t alarm_hdlr_thread;

  /* set up SIGALRM signal handler */
  sem_init(&sigalrm_sem, 0, 0);
  /* block all signals */
  sigemptyset(&sigs_to_block);
  sa.sa_handler = sigalrm;
  sa.sa_mask = sigs_to_block;
  sa.sa_flags = 0;
  sigaction(SIGALRM, &sa, NULL);
  /* set up SIGALRM signal thread */
  pthread_create(&alarm_hdlr_thread, NULL, alarm_hdlr_pthread, (void *) 0);
#if 1
  sigaddset(&sigs_to_block, SIGALRM);
  pthread_sigmask(SIG_SETMASK, &sigs_to_block, NULL);
#endif

  alarm(1);

  for (;;) {
      sigset_t s;
      sigpending(&s);
      printf("pending=%d\n", sigismember(&s, SIGALRM));
      sleep(5);
  }
}
Comment 1 Ulrich Drepper 2003-04-21 21:15:57 EDT
This should work fine when using NPTL (such as in glibc 2.3.2-27.9). 
LinuxThreads is and will remain broken wrt signals.

Note You need to log in before you can comment on or make changes to this bug.