mirror of
https://github.com/golang/go
synced 2024-11-17 01:14:53 -07:00
runtime: revert use of __fork to work around Apple atfork bugs
An Apple engineer suggests that since __fork is not public API,
it would be better to use a different fix. With the benefit of source code,
they suggest using xpc_date_create_from_current instead of
xpc_atfork_child. The latter sets some flags that disable certain
functionality for the remainder of the process lifetime (expecting exec),
while the former should do the necessary setup.
Reverting the __fork fix in order to prepare a clean fix based
on CL 451735 using xpc_date_create_from_current.
This reverts commit c61d322d5f
.
Change-Id: I2da293ff537237ffd2d40ad756d827c95c84635b
Reviewed-on: https://go-review.googlesource.com/c/go/+/460475
Auto-Submit: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
82f09b75ca
commit
0a0de0fc42
@ -78,7 +78,7 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
|
||||
// About to call fork.
|
||||
// No more allocation or calls of non-assembly functions.
|
||||
runtime_BeforeFork()
|
||||
r1, _, err1 = rawSyscall(forkTrampoline, 0, 0, 0)
|
||||
r1, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
|
||||
if err1 != 0 {
|
||||
runtime_AfterFork()
|
||||
return 0, err1
|
||||
@ -276,6 +276,6 @@ childerror:
|
||||
// send error code on pipe
|
||||
rawSyscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
|
||||
for {
|
||||
rawSyscall(exitTrampoline, 253, 0, 0)
|
||||
rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), 253, 0, 0)
|
||||
}
|
||||
}
|
||||
|
@ -22,34 +22,7 @@ func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||
|
||||
// These are called from exec_libc2.go in the child of fork.
|
||||
// The names differ between macOS and OpenBSD, so we need
|
||||
// to declare the specific ones used here to keep the exec_libc2.go
|
||||
// code portable.
|
||||
//
|
||||
// We use __fork and __exit, not fork and exit, to avoid the libc atfork
|
||||
// and atexit handlers. The atfork handlers have caused fork child
|
||||
// hangs in the past (see #33565, #56784). The atexit handlers have
|
||||
// not, but the non-libc ports all invoke the system call, so doing
|
||||
// the same here makes sense. In general we wouldn't expect
|
||||
// atexit handlers to work terribly well in a fork child anyway.
|
||||
// (Also, perhaps the atfork handlers clear the atexit handlers,
|
||||
// in which case we definitely need to avoid calling the libc exit
|
||||
// if we bypass the libc fork.)
|
||||
//
|
||||
// Other calls that are made in the child after the fork are
|
||||
// ptrace, setsid, setpgid, getpid, ioctl, chroot, setgroups,
|
||||
// setgid, setuid, chdir, dup2, fcntl, close, execve, and write.
|
||||
// Those are all simple kernel wrappers that should be safe
|
||||
// to be called directly. The fcntl and ioctl functions do run
|
||||
// some code around the kernel call, but they don't call any
|
||||
// other functions, so for now we keep using them instead of
|
||||
// calling the lower-level __fcntl and __ioctl functions.
|
||||
var (
|
||||
dupTrampoline = abi.FuncPCABI0(libc_dup2_trampoline)
|
||||
exitTrampoline = abi.FuncPCABI0(libc___exit_trampoline)
|
||||
forkTrampoline = abi.FuncPCABI0(libc___fork_trampoline)
|
||||
)
|
||||
var dupTrampoline = abi.FuncPCABI0(libc_dup2_trampoline)
|
||||
|
||||
type SockaddrDatalink struct {
|
||||
Len uint8
|
||||
@ -237,12 +210,11 @@ func Kill(pid int, signum Signal) (err error) { return kill(pid, int(signum), 1)
|
||||
//sys writev(fd int, iovecs []Iovec) (cnt uintptr, err error)
|
||||
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
|
||||
//sys munmap(addr uintptr, length uintptr) (err error)
|
||||
//sysnb __fork() (pid int, err error)
|
||||
//sysnb fork() (pid int, err error)
|
||||
//sysnb ioctl(fd int, req int, arg int) (err error)
|
||||
//sysnb ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_ioctl
|
||||
//sysnb execve(path *byte, argv **byte, envp **byte) (err error)
|
||||
//sysnb exit(res int) (err error)
|
||||
//sysnb __exit(res int) (err error)
|
||||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error)
|
||||
//sys fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) = SYS_fcntl
|
||||
//sys unlinkat(fd int, path string, flags int) (err error)
|
||||
|
@ -10,11 +10,7 @@ import (
|
||||
"internal/abi"
|
||||
)
|
||||
|
||||
var (
|
||||
dupTrampoline = abi.FuncPCABI0(libc_dup3_trampoline)
|
||||
exitTrampoline = abi.FuncPCABI0(libc_exit_trampoline)
|
||||
forkTrampoline = abi.FuncPCABI0(libc_fork_trampoline)
|
||||
)
|
||||
var dupTrampoline = abi.FuncPCABI0(libc_dup3_trampoline)
|
||||
|
||||
func init() {
|
||||
execveOpenBSD = execve
|
||||
|
@ -1734,8 +1734,8 @@ func libc_munmap_trampoline()
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func __fork() (pid int, err error) {
|
||||
r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc___fork_trampoline), 0, 0, 0)
|
||||
func fork() (pid int, err error) {
|
||||
r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
|
||||
pid = int(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
@ -1743,9 +1743,9 @@ func __fork() (pid int, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func libc___fork_trampoline()
|
||||
func libc_fork_trampoline()
|
||||
|
||||
//go:cgo_import_dynamic libc___fork __fork "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic libc_fork fork "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
@ -1801,20 +1801,6 @@ func libc_exit_trampoline()
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func __exit(res int) (err error) {
|
||||
_, _, e1 := rawSyscall(abi.FuncPCABI0(libc___exit_trampoline), uintptr(res), 0, 0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func libc___exit_trampoline()
|
||||
|
||||
//go:cgo_import_dynamic libc___exit __exit "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(mib) > 0 {
|
||||
|
@ -221,16 +221,14 @@ TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_mmap(SB)
|
||||
TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_munmap(SB)
|
||||
TEXT ·libc___fork_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc___fork(SB)
|
||||
TEXT ·libc_fork_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fork(SB)
|
||||
TEXT ·libc_ioctl_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_ioctl(SB)
|
||||
TEXT ·libc_execve_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_execve(SB)
|
||||
TEXT ·libc_exit_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_exit(SB)
|
||||
TEXT ·libc___exit_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc___exit(SB)
|
||||
TEXT ·libc_sysctl_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_sysctl(SB)
|
||||
TEXT ·libc_unlinkat_trampoline(SB),NOSPLIT,$0-0
|
||||
|
@ -1734,8 +1734,8 @@ func libc_munmap_trampoline()
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func __fork() (pid int, err error) {
|
||||
r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc___fork_trampoline), 0, 0, 0)
|
||||
func fork() (pid int, err error) {
|
||||
r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
|
||||
pid = int(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
@ -1743,9 +1743,9 @@ func __fork() (pid int, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func libc___fork_trampoline()
|
||||
func libc_fork_trampoline()
|
||||
|
||||
//go:cgo_import_dynamic libc___fork __fork "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic libc_fork fork "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
@ -1801,20 +1801,6 @@ func libc_exit_trampoline()
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func __exit(res int) (err error) {
|
||||
_, _, e1 := rawSyscall(abi.FuncPCABI0(libc___exit_trampoline), uintptr(res), 0, 0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func libc___exit_trampoline()
|
||||
|
||||
//go:cgo_import_dynamic libc___exit __exit "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(mib) > 0 {
|
||||
|
@ -221,16 +221,14 @@ TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_mmap(SB)
|
||||
TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_munmap(SB)
|
||||
TEXT ·libc___fork_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc___fork(SB)
|
||||
TEXT ·libc_fork_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fork(SB)
|
||||
TEXT ·libc_ioctl_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_ioctl(SB)
|
||||
TEXT ·libc_execve_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_execve(SB)
|
||||
TEXT ·libc_exit_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_exit(SB)
|
||||
TEXT ·libc___exit_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc___exit(SB)
|
||||
TEXT ·libc_sysctl_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_sysctl(SB)
|
||||
TEXT ·libc_unlinkat_trampoline(SB),NOSPLIT,$0-0
|
||||
|
Loading…
Reference in New Issue
Block a user