Currently, on G-register architectures (i.e. all non-x86), we set up TLS only when cgo is used, by libc. The reason is probably that the G register is reserved in Go code and so it should always be valid. However, there are more and more cases where we call external functions even in a non-cgo program, for example, VDSO, and libc calls on darwin. These external functions could potentially clobbers the G register temporarily. If a signal is received during the execution of an external function, we cannot directly use the G register's content as the G. This has caused a number of problems. Currently we play various tricks and workarounds. See e.g. #32912, #34391, #35800.
Maybe we should consider initializing TLS ourselves in non-cgo programs, and always save/restore G in TLS across external calls? This way, we unify the cgo and non-cgo code paths, and can remove various workarounds and maybe potential problems.
The text was updated successfully, but these errors were encountered:
Currently, on darwin/arm64 we set up TLS using cgo. TLS is not
set for pure Go programs. As we use libc for syscalls on darwin,
we need to save the G register before the libc call. Otherwise it
is not signal-safe, as a signal may land during the execution of
a libc function, where the G register may be clobbered.
This CL initializes TLS in Go, by calling the pthread functions
directly without cgo. This makes it possible to save the G
register to TLS in pure Go programs (done in a later CL).
Inspired by Elias's CL 209197. Write the logic in Go instead of
Updates #38485, #35853.
Trust: Cherry Zhang <firstname.lastname@example.org>
Trust: Elias Naur <email@example.com>
Run-TryBot: Cherry Zhang <firstname.lastname@example.org>
TryBot-Result: Go Bot <email@example.com>
Reviewed-by: Ian Lance Taylor <firstname.lastname@example.org>