diff options
| author | Keith Randall <khr@golang.org> | 2022-11-08 17:48:48 -0800 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2022-11-17 23:12:04 +0000 |
| commit | d6171c9be2a4bd2801841aa006702886c476f217 (patch) | |
| tree | 9d1c4a24f0a80b3354ccaeb8c4064a35380acf1b /src/runtime/lfstack.go | |
| parent | 3e5c2c155645ebaed62e4481430c455045b0fff5 (diff) | |
| download | go-d6171c9be2a4bd2801841aa006702886c476f217.tar.xz | |
runtime: fix conflict between lfstack and checkptr
lfstack does very unsafe things. In particular, it will not
work with nodes that live on the heap. In normal use by the runtime,
that is the case (it is only used for gc work bufs). But the lfstack
test does use heap objects. It goes through some hoops to prevent
premature deallocation, but those hoops are not enough to convince
-d=checkptr that everything is ok.
Instead, allocate the test objects outside the heap, like the runtime
does for all of its lfstack usage. Remove the lifetime workaround
from the test.
Reported in https://groups.google.com/g/golang-nuts/c/psjrUV2ZKyI
Change-Id: If611105eab6c823a4d6c105938ce145ed731781d
Reviewed-on: https://go-review.googlesource.com/c/go/+/448899
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/runtime/lfstack.go')
| -rw-r--r-- | src/runtime/lfstack.go | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/src/runtime/lfstack.go b/src/runtime/lfstack.go index 406561a275..306a8e888a 100644 --- a/src/runtime/lfstack.go +++ b/src/runtime/lfstack.go @@ -18,8 +18,7 @@ import ( // This stack is intrusive. Nodes must embed lfnode as the first field. // // The stack does not keep GC-visible pointers to nodes, so the caller -// is responsible for ensuring the nodes are not garbage collected -// (typically by allocating them from manually-managed memory). +// must ensure the nodes are allocated outside the Go heap. type lfstack uint64 func (head *lfstack) push(node *lfnode) { @@ -59,6 +58,9 @@ func (head *lfstack) empty() bool { // lfnodeValidate panics if node is not a valid address for use with // lfstack.push. This only needs to be called when node is allocated. func lfnodeValidate(node *lfnode) { + if base, _, _ := findObject(uintptr(unsafe.Pointer(node)), 0, 0); base != 0 { + throw("lfstack node allocated from the heap") + } if lfstackUnpack(lfstackPack(node, ^uintptr(0))) != node { printlock() println("runtime: bad lfnode address", hex(uintptr(unsafe.Pointer(node)))) |
