File tree Expand file tree Collapse file tree 3 files changed +45
-1
lines changed Expand file tree Collapse file tree 3 files changed +45
-1
lines changed Original file line number Diff line number Diff line change 1+ package issue76126
2+
3+ import (
4+ "sync"
5+ "testing"
6+ )
7+
8+ func TestIssue76126 (t * testing.T ) {
9+ var wg sync.WaitGroup
10+ wg .Go (func () {
11+ panic ("test" )
12+ })
13+ wg .Wait ()
14+ }
Original file line number Diff line number Diff line change @@ -236,7 +236,18 @@ func (wg *WaitGroup) Wait() {
236236func (wg * WaitGroup ) Go (f func ()) {
237237 wg .Add (1 )
238238 go func () {
239- defer wg .Done ()
239+ defer func () {
240+ if x := recover (); x != nil {
241+ // Don't call Done as it may cause Wait to unblock,
242+ // so that the main goroutine races with the runtime.fatal
243+ // resulting from unhandled panic.
244+ panic (x )
245+ }
246+
247+ // f completed normally, or abruptly using goexit.
248+ // Either way, decrement the semaphore.
249+ wg .Done ()
250+ }()
240251 f ()
241252 }()
242253}
Original file line number Diff line number Diff line change 55package sync_test
66
77import (
8+ "internal/testenv"
9+ "os/exec"
10+ "path/filepath"
811 . "sync"
912 "sync/atomic"
1013 "testing"
@@ -110,6 +113,22 @@ func TestWaitGroupGo(t *testing.T) {
110113 }
111114}
112115
116+ func TestIssue76126 (t * testing.T ) {
117+ testenv .MustHaveGoRun (t )
118+
119+ cmd := exec .Command (testenv .GoToolPath (t ), "test" , "-race" )
120+ cmd .Dir = filepath .Join ("testdata" , "issue76126" )
121+ b , err := cmd .CombinedOutput ()
122+ if err != nil {
123+ t .Fatalf ("go test -race failed: %v\n %s" , err , b )
124+ }
125+ if code := cmd .ProcessState .ExitCode (); code == 0 {
126+ t .Fatalf ("expected non-zero exit code, got %d" , code )
127+ }
128+
129+ // Should fail with panic.
130+ }
131+
113132func BenchmarkWaitGroupUncontended (b * testing.B ) {
114133 type PaddedWaitGroup struct {
115134 WaitGroup
You can’t perform that action at this time.
0 commit comments