From 5a5854c2d1a0eed6d48734ab2cc674c25aa670cb Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Tue, 22 Oct 2019 11:59:00 -0700 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Austin Clements --- src/runtime/checkptr.go | 40 ++++++++++++++++++++++++++++++++++++---- 1 file 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 } -- 2.50.0