From f7f9c8f2fb61fde1a109e277f27a30b610e67ed0 Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Tue, 19 May 2020 01:29:11 -0400 Subject: [PATCH] runtime: allocate fewer bytes during TestEINTR This will hopefully address the occasional "runtime: out of memory" failures observed on the openbsd-arm-jsing builder: https://build.golang.org/log/c296d866e5d99ba401b18c1a2ff3e4d480e5238c Also make the "spin" and "winch" loops concurrent instead of sequential to cut down the test's running time. Finally, change Block to coordinate by closing stdin instead of sending SIGINT. The SIGINT handler wasn't necessarily registered by the time the signal was sent. Updates #20400 Updates #39043 Change-Id: Ie12fc75b87e33847dc25a12edb4126db27492da6 Reviewed-on: https://go-review.googlesource.com/c/go/+/234538 Run-TryBot: Bryan C. Mills TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/runtime/testdata/testprogcgo/eintr.go | 31 +++++++++++++---------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/runtime/testdata/testprogcgo/eintr.go b/src/runtime/testdata/testprogcgo/eintr.go index 58f0dd2ca3..9d9435d9a6 100644 --- a/src/runtime/testdata/testprogcgo/eintr.go +++ b/src/runtime/testdata/testprogcgo/eintr.go @@ -32,11 +32,11 @@ import ( "errors" "fmt" "io" + "io/ioutil" "log" "net" "os" "os/exec" - "os/signal" "sync" "syscall" "time" @@ -71,14 +71,15 @@ func EINTR() { // spin does CPU bound spinning and allocating for a millisecond, // to get a SIGURG. //go:noinline -func spin() (float64, [][]byte) { +func spin() (float64, []byte) { stop := time.Now().Add(time.Millisecond) r1 := 0.0 - var r2 [][]byte + r2 := make([]byte, 200) for time.Now().Before(stop) { for i := 1; i < 1e6; i++ { r1 += r1 / float64(i) - r2 = append(r2, bytes.Repeat([]byte{byte(i)}, 100)) + r2 = append(r2, bytes.Repeat([]byte{byte(i)}, 100)...) + r2 = r2[100:] } } return r1, r2 @@ -96,8 +97,13 @@ func winch() { // sendSomeSignals triggers a few SIGURG and SIGWINCH signals. func sendSomeSignals() { - spin() + done := make(chan struct{}) + go func() { + spin() + close(done) + }() winch() + <-done } // testPipe tests pipe operations. @@ -212,6 +218,10 @@ func testExec(wg *sync.WaitGroup) { go func() { defer wg.Done() cmd := exec.Command(os.Args[0], "Block") + stdin, err := cmd.StdinPipe() + if err != nil { + log.Fatal(err) + } cmd.Stderr = new(bytes.Buffer) cmd.Stdout = cmd.Stderr if err := cmd.Start(); err != nil { @@ -220,9 +230,7 @@ func testExec(wg *sync.WaitGroup) { go func() { sendSomeSignals() - if err := cmd.Process.Signal(os.Interrupt); err != nil { - panic(err) - } + stdin.Close() }() if err := cmd.Wait(); err != nil { @@ -231,10 +239,7 @@ func testExec(wg *sync.WaitGroup) { }() } -// Block blocks until the process receives os.Interrupt. +// Block blocks until stdin is closed. func Block() { - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - defer signal.Stop(c) - <-c + io.Copy(ioutil.Discard, os.Stdin) }