diff options
author | Matthew Dempsky <mdempsky@google.com> | 2019-10-22 11:59:00 -0700 |
---|---|---|
committer | Matthew Dempsky <mdempsky@google.com> | 2019-10-22 23:14:03 +0000 |
commit | 5a5854c2d1a0eed6d48734ab2cc674c25aa670cb (patch) | |
tree | 9fbc1306a8b81fddb292a527c5250d9d921ce707 | |
parent | 7d84245a9cd41489984e36c5a01876fc4da5d5ec (diff) | |
download | go-5a5854c2d1a0eed6d48734ab2cc674c25aa670cb.tar.gz go-5a5854c2d1a0eed6d48734ab2cc674c25aa670cb.zip |
runtime: fix -d=checkptr failure for testing/quick
This CL extends checkptrBase to recognize pointers into the stack and
data/bss sections. I was meaning to do this eventually anyway, but
it's also an easy way to workaround #35068.
Updates #35068.
Change-Id: Ib47f0aa800473a4fbc249da52ff03bec32c3ebe2
Reviewed-on: https://go-review.googlesource.com/c/go/+/202639
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
-rw-r--r-- | src/runtime/checkptr.go | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/src/runtime/checkptr.go b/src/runtime/checkptr.go index 94581ba5c9..3c6a40206f 100644 --- a/src/runtime/checkptr.go +++ b/src/runtime/checkptr.go @@ -64,9 +64,41 @@ func checkptrArithmetic(p unsafe.Pointer, originals []unsafe.Pointer) { panic(ptrArithError{p, originals}) } +// checkptrBase returns the base address for the allocation containing +// the address p. +// +// Importantly, if p1 and p2 point into the same variable, then +// checkptrBase(p1) == checkptrBase(p2). However, the converse/inverse +// is not necessarily true as allocations can have trailing padding, +// and multiple variables may be packed into a single allocation. func checkptrBase(p unsafe.Pointer) uintptr { - base, _, _ := findObject(uintptr(p), 0, 0) - // TODO(mdempsky): If base == 0, then check if p points to the - // stack or a global variable. - return base + // stack + if gp := getg(); gp.stack.lo <= uintptr(p) && uintptr(p) < gp.stack.hi { + // TODO(mdempsky): Walk the stack to identify the + // specific stack frame or even stack object that p + // points into. + // + // In the mean time, use "1" as a pseudo-address to + // represent the stack. This is an invalid address on + // all platforms, so it's guaranteed to be distinct + // from any of the addresses we might return below. + return 1 + } + + // heap (must check after stack because of #35068) + if base, _, _ := findObject(uintptr(p), 0, 0); base != 0 { + return base + } + + // data or bss + for _, datap := range activeModules() { + if datap.data <= uintptr(p) && uintptr(p) < datap.edata { + return datap.data + } + if datap.bss <= uintptr(p) && uintptr(p) < datap.ebss { + return datap.bss + } + } + + return 0 } |