| Summary: | libc_r: non-delivery of previously blocked signals | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | Anton Berezin <tobez> | ||||
| Component: | bin | Assignee: | freebsd-bugs (Nobody) <bugs> | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | CC: | deischen | ||||
| Priority: | Normal | ||||||
| Version: | 5.0-CURRENT | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
State Changed From-To: open->closed Fixed has been applied to both -current and -stable. |
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; }