mirror of https://github.com/golang/go.git
[release-branch.go1.23] syscall: don't send child signal when testing pidfd
Avoid a spurious SIGCHLD the first time we start a process. For #71828 Fixes #71848 Change-Id: I744100d21bf6aaaaafc99bc5eec9f9f807a50682 Reviewed-on: https://go-review.googlesource.com/c/go/+/651055 Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
2aaa388971
commit
c57e2bd22c
|
|
@ -11,12 +11,15 @@ import (
|
||||||
"internal/testenv"
|
"internal/testenv"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"os/signal"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -24,6 +27,7 @@ import (
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registerHelperCommand("pwd", cmdPwd)
|
registerHelperCommand("pwd", cmdPwd)
|
||||||
|
registerHelperCommand("signaltest", cmdSignalTest)
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmdPwd(...string) {
|
func cmdPwd(...string) {
|
||||||
|
|
@ -274,3 +278,55 @@ func TestExplicitPWD(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue 71828.
|
||||||
|
func TestSIGCHLD(t *testing.T) {
|
||||||
|
cmd := helperCommand(t, "signaltest")
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
t.Logf("%s", out)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cmdSignaltest is for TestSIGCHLD.
|
||||||
|
// This runs in a separate process because the bug only happened
|
||||||
|
// the first time that a child process was started.
|
||||||
|
func cmdSignalTest(...string) {
|
||||||
|
chSig := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(chSig, syscall.SIGCHLD)
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
c := 0
|
||||||
|
for range chSig {
|
||||||
|
c++
|
||||||
|
fmt.Printf("SIGCHLD %d\n", c)
|
||||||
|
if c > 1 {
|
||||||
|
fmt.Println("too many SIGCHLD signals")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
defer func() {
|
||||||
|
signal.Reset(syscall.SIGCHLD)
|
||||||
|
close(chSig)
|
||||||
|
wg.Wait()
|
||||||
|
}()
|
||||||
|
|
||||||
|
exe, err := os.Executable()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("os.Executable failed: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command(exe, "hang", "200ms")
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
fmt.Printf("failed to run child process: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -803,7 +803,7 @@ func os_checkClonePidfd() error {
|
||||||
//
|
//
|
||||||
//go:noinline
|
//go:noinline
|
||||||
func doCheckClonePidfd(pidfd *int32) (pid uintptr, errno Errno) {
|
func doCheckClonePidfd(pidfd *int32) (pid uintptr, errno Errno) {
|
||||||
flags := uintptr(CLONE_VFORK|CLONE_VM|CLONE_PIDFD|SIGCHLD)
|
flags := uintptr(CLONE_VFORK | CLONE_VM | CLONE_PIDFD)
|
||||||
if runtime.GOARCH == "s390x" {
|
if runtime.GOARCH == "s390x" {
|
||||||
// On Linux/s390, the first two arguments of clone(2) are swapped.
|
// On Linux/s390, the first two arguments of clone(2) are swapped.
|
||||||
pid, errno = rawVforkSyscall(SYS_CLONE, 0, flags, uintptr(unsafe.Pointer(pidfd)))
|
pid, errno = rawVforkSyscall(SYS_CLONE, 0, flags, uintptr(unsafe.Pointer(pidfd)))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue