mirror of
git://sourceware.org/git/glibc.git
synced 2025-02-17 13:00:43 +08:00
The fix for bug #15368 was unnecessarily Linux-specific. To recap, POSIX specifies raise to be async-signal-safe, but also specifies it to be equivalent to pthread_kill(pthread_self(), sig), which is not an async-signal-safe sequence of operations; a signal handler could run in between pthread_self and pthread_kill, and do something (such as calling fork, which is also async-signal-safe) that would invalidate the thread descriptor. This is even true in the hypothetical case of a port that doesn't implement multithreading: kill(getpid(), sig) will fire the signal twice if a signal handler runs in between, calls fork, and then returns on both sides of the fork. I don't see anything in the standards to forbid that. The Linux-specific fix was to override the definitions of raise in both libpthread and libc to the same unitary function that blocks signals, retrieves TID and PID directly from the kernel, calls tgkill, and only then unblocks signals. This patch generalizes that to any port: pthread_kill is moved from libpthread to libc, with a forwarding stub left behind. The definition of raise in libpthread is also replaced with a forwarding stub. The Linux-specific definition of raise is deleted; those ports will now use sysdeps/pthread/raise.c, which blocks signals first, then calls pthread_self and pthread_kill, and then unblocks signals. Similarly, sysdeps/posix/raise.c (which would be used on a port that didn't implement multithreading) blocks signals, calls getpid and kill, and then unblocks signals. Thus, ports need only implement the primitives correctly and do not need to worry about making raise async-signal-safe. The only wrinkle was that up till now, we did not bother initializing the ->tid field of the initial thread's descriptor unless libpthread was loaded; now that raise calls pthread_kill even in a single- threaded environment, that won't fly. This is abstractly easy to fix; the tricky part was figuring out _where_ to put the calls (two of them, as it happens) to __pthread_initialize_pids, and I'd appreciate careful eyes on those changes. You might be wondering why it's safe to rely on the TID in the thread descriptor, rather than calling gettid directly. Since all signals are blocked from before calling pthread_self until after pthread_kill uses the TID to call tgkill, the question is whether some _other_ thread could do something that would invalidate the calling thread's descriptor, and I believe there is no such thing. While I was at it I fixed another bug: raise was returning an error code on failure (like pthread_kill does) instead of setting errno as specified. This is user-visible but I don't think it's worth recording as a fixed bug, nobody bothers checking whether raise failed anyway. * nptl/pt-raise.c * sysdeps/unix/sysv/linux/pt-raise.c * sysdeps/unix/sysv/linux/raise.c: Remove file. * sysdeps/unix/sysv/linux/pthread_kill.c: Use __is_internal_signal to check for forbidden signals. Use INTERNAL_SYSCALL_CALL to call getpid. Provide __libc_pthread_kill, with __pthread_kill as strong alias and pthread_kill as weak alias. * sysdeps/posix/raise.c: Block signals around the calls to __getpid and __kill. Provide __libc_raise, with raise as strong alias, libc_hidden_def for raise, and gsignal as weak alias. * sysdeps/pthread/raise.c: New file. Implement by blocking signals, calling pthread_self and pthread_kill, and then unblocking signals again. Provide same symbols as above. * sysdeps/generic/internal-signals.h: Define all of the same functions that sysdeps/unix/sysv/linux/internal-signals.h does, with sensible default definitions. * sysdeps/unix/sysv/linux/internal-signals.h: Clarify comments. * nptl/pthread_kill.c: Define __libc_pthread_kill, with __pthread_kill as strong alias and pthread_kill as weak alias. * nptl/pthread_self.c: Define __pthread_self, with pthread_self as weak alias. * signal/raise.c: Define __libc_raise, with raise as strong alias, libc_hidden_def for raise, and gsignal as weak alias. * nptl/Makefile: Move pthread_kill from libpthread-routines to routines. Remove pt-raise from libpthread-routines. * nptl/Versions (libc/GLIBC_2.28): Add pthread_kill. (libc/GLIBC_PRIVATE): Add __libc_pthread_kill and __libc_raise. * sysdeps/generic/pt-compat-stubs.S: Add stubs for raise and pthread_kill. * nptl/nptl-init.c (__pthread_initialize_minimal_internal): Don't call __pthread_initialize_pids here. * csu/libc-tls.c (__libc_setup_tls): Call __pthread_initialize_pids after all other setup. * elf/rtld.c (init_tls): Likewise. * include/pthreadP.h: New forwarder. * include/pthread.h: Add multiple inclusion guard. Declare __pthread_self. * include/signal.h: Declare __pthread_kill. * sysdeps/**/libc.abilist (GLIBC_2.28): Add pthread_kill. |
||
---|---|---|
argp | ||
assert | ||
benchtests | ||
bits | ||
catgets | ||
ChangeLog.old | ||
conform | ||
crypt | ||
csu | ||
ctype | ||
debug | ||
dirent | ||
dlfcn | ||
elf | ||
gmon | ||
gnulib | ||
grp | ||
gshadow | ||
hesiod | ||
hurd | ||
iconv | ||
iconvdata | ||
include | ||
inet | ||
intl | ||
io | ||
libidn | ||
libio | ||
locale | ||
localedata | ||
login | ||
mach | ||
malloc | ||
manual | ||
math | ||
mathvec | ||
misc | ||
nis | ||
nptl | ||
nptl_db | ||
nscd | ||
nss | ||
po | ||
posix | ||
pwd | ||
resolv | ||
resource | ||
rt | ||
scripts | ||
setjmp | ||
shadow | ||
signal | ||
socket | ||
soft-fp | ||
stdio-common | ||
stdlib | ||
streams | ||
string | ||
sunrpc | ||
support | ||
sysdeps | ||
sysvipc | ||
termios | ||
time | ||
timezone | ||
wcsmbs | ||
wctype | ||
.gitattributes | ||
.gitignore | ||
abi-tags | ||
aclocal.m4 | ||
ChangeLog | ||
config.h.in | ||
config.make.in | ||
configure | ||
configure.ac | ||
COPYING | ||
COPYING.LIB | ||
extra-lib.mk | ||
gen-locales.mk | ||
INSTALL | ||
libc-abis | ||
libof-iterator.mk | ||
LICENSES | ||
MAINTAINERS | ||
Makeconfig | ||
Makefile | ||
Makefile.in | ||
Makerules | ||
NEWS | ||
o-iterator.mk | ||
README | ||
Rules | ||
shlib-versions | ||
test-skeleton.c | ||
version.h |
This directory contains the sources of the GNU C Library. See the file "version.h" for what release version you have. The GNU C Library is the standard system C library for all GNU systems, and is an important part of what makes up a GNU system. It provides the system API for all programs written in C and C-compatible languages such as C++ and Objective C; the runtime facilities of other programming languages use the C library to access the underlying operating system. In GNU/Linux systems, the C library works with the Linux kernel to implement the operating system behavior seen by user applications. In GNU/Hurd systems, it works with a microkernel and Hurd servers. The GNU C Library implements much of the POSIX.1 functionality in the GNU/Hurd system, using configurations i[4567]86-*-gnu. The current GNU/Hurd support requires out-of-tree patches that will eventually be incorporated into an official GNU C Library release. When working with Linux kernels, this version of the GNU C Library requires Linux kernel version 3.2 or later. Also note that the shared version of the libgcc_s library must be installed for the pthread library to work correctly. The GNU C Library supports these configurations for using Linux kernels: aarch64*-*-linux-gnu alpha*-*-linux-gnu arm-*-linux-gnueabi hppa-*-linux-gnu i[4567]86-*-linux-gnu x86_64-*-linux-gnu Can build either x86_64 or x32 ia64-*-linux-gnu m68k-*-linux-gnu microblaze*-*-linux-gnu mips-*-linux-gnu mips64-*-linux-gnu powerpc-*-linux-gnu Hardware or software floating point, BE only. powerpc64*-*-linux-gnu Big-endian and little-endian. s390-*-linux-gnu s390x-*-linux-gnu riscv64-*-linux-gnu sh[34]-*-linux-gnu sparc*-*-linux-gnu sparc64*-*-linux-gnu tilegx-*-linux-gnu If you are interested in doing a port, please contact the glibc maintainers; see http://www.gnu.org/software/libc/ for more information. See the file INSTALL to find out how to configure, build, and install the GNU C Library. You might also consider reading the WWW pages for the C library at http://www.gnu.org/software/libc/. The GNU C Library is (almost) completely documented by the Texinfo manual found in the `manual/' subdirectory. The manual is still being updated and contains some known errors and omissions; we regret that we do not have the resources to work on the manual as much as we would like. For corrections to the manual, please file a bug in the `manual' component, following the bug-reporting instructions below. Please be sure to check the manual in the current development sources to see if your problem has already been corrected. Please see http://www.gnu.org/software/libc/bugs.html for bug reporting information. We are now using the Bugzilla system to track all bug reports. This web page gives detailed information on how to report bugs properly. The GNU C Library is free software. See the file COPYING.LIB for copying conditions, and LICENSES for notices about a few contributions that require these additional notices to be distributed. License copyright years may be listed using range notation, e.g., 1996-2015, indicating that every year in the range, inclusive, is a copyrightable year that would otherwise be listed individually.