Skip to content

Commit 0929d21

Browse files
mknyszekgopherbot
authored andcommitted
cmd/go: keep objects alive while stopping cleanups
There are two places in cmd/go where cleanups are stopped before they fire, and where the objects the cleanups are attached to may be dead while we call Stop. This is essentially a race between Stop and the cleanup being called. This can be fine, but these cleanups are used as a way to check some invariants, so just panic if they're executed. As a result, if they fire erroneously, they'll take down the whole process, even if no invariant was actually violated. The runtime.Cleanup.Stop documentation explains that users of Stop need to hold the object alive across the call to Stop if they want to be sure that Stop succeeds, so do that here by adding an explicit runtime.KeepAlive call. Kudos to Michael Pratt for finding the issue. Fixes #74780. Change-Id: I22e6f4642ac68f727ca3781f5d39a85015047925 Reviewed-on: https://go-review.googlesource.com/c/go/+/719961 Auto-Submit: Michael Knyszek <[email protected]> Reviewed-by: Michael Pratt <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Carlos Amedee <[email protected]>
1 parent f03d06e commit 0929d21

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed

src/cmd/go/internal/base/limit.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ func AcquireNet() (release func(), err error) {
6363
<-netLimitSem
6464
}
6565
cleanup.Stop()
66+
67+
// checker may be dead at the moment after we last access
68+
// it in this function, so the cleanup can fire before Stop
69+
// completes. Keep checker alive while we call Stop. See
70+
// the documentation for runtime.Cleanup.Stop.
71+
runtime.KeepAlive(checker)
6672
}, nil
6773
}
6874

src/cmd/go/internal/lockedfile/lockedfile.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ func (f *File) Close() error {
9494

9595
err := closeFile(f.osFile.File)
9696
f.cleanup.Stop()
97+
// f may be dead at the moment after we access f.cleanup,
98+
// so the cleanup can fire before Stop completes. Keep f
99+
// alive while we call Stop. See the documentation for
100+
// runtime.Cleanup.Stop.
101+
runtime.KeepAlive(f)
97102
return err
98103
}
99104

0 commit comments

Comments
 (0)