diff options
| author | Michael Anthony Knyszek <mknyszek@google.com> | 2025-11-07 18:22:29 +0000 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2025-11-14 11:15:44 -0800 |
| commit | 80c91eedbbf3c041e9b0c03c28fae2c73dbb7df4 (patch) | |
| tree | 30f816fc0c7f9748ac51a86337084d5187cbef73 /src/runtime | |
| parent | 7a8d0b5d53dc7be331016b6903707aa256e22c2a (diff) | |
| download | go-80c91eedbbf3c041e9b0c03c28fae2c73dbb7df4.tar.xz | |
runtime: ensure weak handles end up in their own allocation
Currently weak handles are atomic.Uintptr values that may end up in
a tiny block which can cause all sorts of surprising leaks. See #76007
for one example.
This change pads out the underlying allocation of the atomic.Uintptr to
16 bytes to ensure we bypass the tiny allocator, and it gets its own
block. This wastes 8 bytes per weak handle. We could potentially do
better by using the 8 byte noscan size class, but this can be a
follow-up change.
For #76007.
Change-Id: I3ab74dda9bf312ea0007f167093052de28134944
Reviewed-on: https://go-review.googlesource.com/c/go/+/719960
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/mheap.go | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/runtime/mheap.go b/src/runtime/mheap.go index 711c7790eb..3334099092 100644 --- a/src/runtime/mheap.go +++ b/src/runtime/mheap.go @@ -2534,7 +2534,15 @@ func getOrAddWeakHandle(p unsafe.Pointer) *atomic.Uintptr { s := (*specialWeakHandle)(mheap_.specialWeakHandleAlloc.alloc()) unlock(&mheap_.speciallock) - handle := new(atomic.Uintptr) + // N.B. Pad the weak handle to ensure it doesn't share a tiny + // block with any other allocations. This can lead to leaks, such + // as in go.dev/issue/76007. As an alternative, we could consider + // using the currently-unused 8-byte noscan size class. + type weakHandleBox struct { + h atomic.Uintptr + _ [maxTinySize - unsafe.Sizeof(atomic.Uintptr{})]byte + } + handle := &(new(weakHandleBox).h) s.special.kind = _KindSpecialWeakHandle s.handle = handle handle.Store(uintptr(p)) |
