1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-12-24 17:51:17 +03:00

nptl: Perform signal initialization upon pthread_create

Install signal handlers and unblock signals before pthread_create
creates the first thread.

create_thread in sysdeps/unix/sysv/linux/createthread.c can send
SIGCANCEL to the current thread, so the SIGCANCEL handler is currently
needed even if pthread_cancel is never called.  (The way timer_create
uses SIGCANCEL does not need a signal handler; both SIG_DFL and SIG_IGN
dispositions should work.)

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
This commit is contained in:
Florian Weimer
2021-05-21 22:35:00 +02:00
parent 06a36b70f9
commit 2f69522d46
5 changed files with 130 additions and 87 deletions

View File

@@ -56,6 +56,43 @@ static struct rtld_global *__nptl_rtld_global __attribute_used__
= &_rtld_global;
#endif
/* This performs the initialization necessary when going from
single-threaded to multi-threaded mode for the first time. */
static void
late_init (void)
{
struct sigaction sa;
__sigemptyset (&sa.sa_mask);
/* Install the cancellation signal handler (in static builds only if
pthread_cancel has been linked in). If for some reason we cannot
install the handler we do not abort. Maybe we should, but it is
only asynchronous cancellation which is affected. */
#ifndef SHARED
extern __typeof (__nptl_sigcancel_handler) __nptl_sigcancel_handler
__attribute__ ((weak));
if (__nptl_sigcancel_handler != NULL)
#endif
{
sa.sa_sigaction = __nptl_sigcancel_handler;
sa.sa_flags = SA_SIGINFO;
(void) __libc_sigaction (SIGCANCEL, &sa, NULL);
}
/* Install the handle to change the threads' uid/gid. */
sa.sa_sigaction = __nptl_setxid_sighandler;
sa.sa_flags = SA_SIGINFO | SA_RESTART;
(void) __libc_sigaction (SIGSETXID, &sa, NULL);
/* The parent process might have left the signals blocked. Just in
case, unblock it. We reuse the signal mask in the sigaction
structure. It is already cleared. */
__sigaddset (&sa.sa_mask, SIGCANCEL);
__sigaddset (&sa.sa_mask, SIGSETXID);
INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_UNBLOCK, &sa.sa_mask,
NULL, __NSIG_BYTES);
}
/* Code to allocate and deallocate a stack. */
#include "allocatestack.c"
@@ -459,9 +496,13 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
{
STACK_VARIABLES;
/* Avoid a data race in the multi-threaded case. */
/* Avoid a data race in the multi-threaded case, and call the
deferred initialization only once. */
if (__libc_single_threaded)
__libc_single_threaded = 0;
{
late_init ();
__libc_single_threaded = 0;
}
const struct pthread_attr *iattr = (struct pthread_attr *) attr;
union pthread_attr_transparent default_attr;