| Summary: | sigprocmask problem with pthread | ||
|---|---|---|---|
| Product: | Base System | Reporter: | jagarl <jagarl> |
| Component: | bin | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 4.2-RELEASE | ||
| Hardware: | Any | ||
| OS: | Any | ||
State Changed From-To: open->closed In a multithreaded process (our threads library), sigprocmask only changes the signal mask for the calling thread. It doesn't affect the signal mask of the _process_. The only way to block a signal in a multithreaded process is to use sigaction() with sa_handler set to SIG_IGN. Posix Std 1003.1, 1996 specifies that the behaviour of sigprocmask in a multi-threaded process is undefined. FreeBSD behaviour of sigprocmask in a multithreaded process should be similar to that of Solaris, which also makes sigprocmask behave the same as pthread_setmask. |
I want to block a signal by sigprocmask, but the signal is not blocked. Following description is for SIGTERM signal. In pthread library, signal is trapped by thread_sig_handler(). If the signal mask is set, the signal blocks in the handler. But thread_init() sets thread_sig_hander() as signal handler only for _SCHED_SIGNAL, SIGINFO and SIGCHLD. When the SIGTERM signal is caught, the signal is processed in kernel and default handler (kill process) is called. If I set some signal hander for SIGTERM, then thread_sig_handler() is used as the signal handler for SIGTERM. Then the signal mask is correctly used. How-To-Repeat: Compile this program with -pthread option. For example, cc test.c -pthread This program should block 'SIGTERM' signal, but 'kill -TERM pid' kills this program. #include <signal.h> int main() { sigset_t tset; sigemptyset(&tset); sigaddset(&tset, SIGTERM); sigprocmask(SIG_BLOCK,&tset,NULL); while(1) ; } But this program correctly blocks the signal. #include <signal.h> void handler(int sig) { _exit(0); } int main() { sigset_t tset; sigemptyset(&tset); sigaddset(&tset, SIGTERM); sigprocmask(SIG_BLOCK,&tset,NULL); signal(SIGTERM,handler); while(1) ; }