Bug 23647

Summary: libc_r: non-delivery of previously blocked signals
Product: Base System Reporter: Anton Berezin <tobez>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me CC: deischen
Priority: Normal    
Version: 5.0-CURRENT   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description Anton Berezin 2000-12-19 18:00:04 UTC
In the program below the SIGINT signal should be delivered immediately
after SIGHUP handler returns.  This does not happen on recent -current
and -stable boxes.

The same program compiled with libc works fine.  It also works right on
3.5, 4.1.1 and older -current boxes.

It appears that pending signals are simply discarded in
_thread_sig_handle_pending() after thread_sig_find() being unable to
find the thread to deliver the signal due to the signal being blocked.

Fix: I am too unfamiliar with uthread code, so I am afraid the fix below a)
slows down _thread_kern_scheduler(); and b) might break some things.
Nevertheless, here is my take:
How-To-Repeat: 
Run the following program compiled with -pthread.  The expected output
is `:-)', any other output is wrong.

#include <sys/types.h>
#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

char sequence[64];
int seqi = 0;
int self;

void hupper(int s)
{
   sequence[seqi++] = ':';
   kill(self,SIGINT);
   sleep(2);
   sequence[seqi++] = '-';
}

void inter(int s)
{
   sequence[seqi++] = ')';
}

int main(void)
{
   struct sigaction sa;

   self = getpid();
   bzero(&sa, sizeof(sa));
   sa.sa_handler = hupper;
   sigaddset(&sa.sa_mask, SIGINT);
   sigaction(SIGHUP, &sa, NULL);
   signal(SIGINT, inter);
   kill(self,SIGHUP);
   sleep(1);
   sequence[seqi++] = '\0';
   printf("%s\n", sequence);
   return 0;
}
Comment 1 Daniel Eischen freebsd_committer freebsd_triage 2000-12-22 04:24:16 UTC
State Changed
From-To: open->closed

Fixed has been applied to both -current and -stable.