aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2025-02-19 17:37:49 -0800
committerMichael Pratt <mpratt@google.com>2025-02-26 09:45:28 -0800
commitc57e2bd22c2ca4537987b696ec7ad141b8d8e5ed (patch)
tree208fa110282c5826dd57c1e427f91a0fad10ca84
parent2aaa3889710327925937e4bdfb0392d68a1e1afe (diff)
downloadgo-c57e2bd22c2ca4537987b696ec7ad141b8d8e5ed.tar.xz
[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>
-rw-r--r--src/os/exec/exec_posix_test.go56
-rw-r--r--src/syscall/exec_linux.go2
2 files changed, 57 insertions, 1 deletions
diff --git a/src/os/exec/exec_posix_test.go b/src/os/exec/exec_posix_test.go
index 5d828b3475..7c77bfa712 100644
--- a/src/os/exec/exec_posix_test.go
+++ b/src/os/exec/exec_posix_test.go
@@ -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)
+ }
+}
diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
index dfd9a8368a..e8ba342954 100644
--- a/src/syscall/exec_linux.go
+++ b/src/syscall/exec_linux.go
@@ -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)))