aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2019-10-22 11:59:00 -0700
committerMatthew Dempsky <mdempsky@google.com>2019-10-22 23:14:03 +0000
commit5a5854c2d1a0eed6d48734ab2cc674c25aa670cb (patch)
tree9fbc1306a8b81fddb292a527c5250d9d921ce707
parent7d84245a9cd41489984e36c5a01876fc4da5d5ec (diff)
downloadgo-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.go40
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
}