[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:
Ian Lance Taylor 2025-02-19 17:37:49 -08:00 committed by Michael Pratt
parent 2aaa388971
commit c57e2bd22c
2 changed files with 57 additions and 1 deletions

View File

@ -11,12 +11,15 @@ import (
"internal/testenv"
"io"
"os"
"os/exec"
"os/signal"
"os/user"
"path/filepath"
"reflect"
"runtime"
"strconv"
"strings"
"sync"
"syscall"
"testing"
"time"
@ -24,6 +27,7 @@ import (
func init() {
registerHelperCommand("pwd", cmdPwd)
registerHelperCommand("signaltest", cmdSignalTest)
}
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)
}
}

View File

@ -803,7 +803,7 @@ func os_checkClonePidfd() error {
//
//go:noinline
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" {
// On Linux/s390, the first two arguments of clone(2) are swapped.
pid, errno = rawVforkSyscall(SYS_CLONE, 0, flags, uintptr(unsafe.Pointer(pidfd)))