mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
syscall: syscall.AllThreadsSyscall signal handling fixes
The runtime support for syscall.AllThreadsSyscall() functions had some corner case deadlock issues when signal handling was in use. This was observed in at least 3 build test failures on ppc64 and amd64 architecture CGO_ENABLED=0 builds over the last few months. The fixes involve more controlled handling of signals while the AllThreads mechanism is being executed. Further details are discussed in bug #44193. The all-threads syscall support is new in go1.16, so earlier releases are not affected by this bug. Fixes #44193 Change-Id: I01ba8508a6e1bb2d872751f50da86dd07911a41d Reviewed-on: https://go-review.googlesource.com/c/go/+/305149 Reviewed-by: Michael Pratt <mpratt@google.com> Trust: Michael Pratt <mpratt@google.com> Trust: Ian Lance Taylor <iant@golang.org> Run-TryBot: Michael Pratt <mpratt@google.com> TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
parent
54af9fd9e6
commit
7e97e4e8cc
4 changed files with 96 additions and 7 deletions
|
|
@ -16,6 +16,7 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"runtime/trace"
|
||||
"strconv"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
|
@ -854,3 +855,44 @@ func TestNotifyContextStringer(t *testing.T) {
|
|||
t.Errorf("c.String() = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// #44193 test signal handling while stopping and starting the world.
|
||||
func TestSignalTrace(t *testing.T) {
|
||||
done := make(chan struct{})
|
||||
quit := make(chan struct{})
|
||||
c := make(chan os.Signal, 1)
|
||||
Notify(c, syscall.SIGHUP)
|
||||
|
||||
// Source and sink for signals busy loop unsynchronized with
|
||||
// trace starts and stops. We are ultimately validating that
|
||||
// signals and runtime.(stop|start)TheWorldGC are compatible.
|
||||
go func() {
|
||||
defer close(done)
|
||||
defer Stop(c)
|
||||
pid := syscall.Getpid()
|
||||
for {
|
||||
select {
|
||||
case <-quit:
|
||||
return
|
||||
default:
|
||||
syscall.Kill(pid, syscall.SIGHUP)
|
||||
}
|
||||
waitSig(t, c, syscall.SIGHUP)
|
||||
}
|
||||
}()
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
buf := new(bytes.Buffer)
|
||||
if err := trace.Start(buf); err != nil {
|
||||
t.Fatalf("[%d] failed to start tracing: %v", i, err)
|
||||
}
|
||||
time.After(1 * time.Microsecond)
|
||||
trace.Stop()
|
||||
size := buf.Len()
|
||||
if size == 0 {
|
||||
t.Fatalf("[%d] trace is empty", i)
|
||||
}
|
||||
}
|
||||
close(quit)
|
||||
<-done
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue