internal/gocore: extract type name of method value from its wrapper function name
It's a single-entry closure laid out like `{pc uintptr, x T}`, and the target pc is for wrapper functions named like pkg.T.m-fm or pkg.(*T).m-fm.
So, extract the type name pkg.T or *pkg.T from its wrapper function name.
Change-Id: I2b5a2db60ee4d875cd0b9ffb3c4f21a69eef0459
GitHub-Last-Rev: 06c4fafc0dcb54bed351ff2f208238d4a43decad
GitHub-Pull-Request: golang/debug#13
Reviewed-on: https://go-review.googlesource.com/c/debug/+/419179
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/internal/gocore/type.go b/internal/gocore/type.go
index 05d15b9..5a944c7 100644
--- a/internal/gocore/type.go
+++ b/internal/gocore/type.go
@@ -6,6 +6,7 @@
import (
"fmt"
+ "regexp"
"strings"
"golang.org/x/debug/internal/core"
@@ -545,6 +546,29 @@
return fr.p.proc.ReadInt(a)
}
+// Match wrapper function name for method value.
+// eg. main.(*Bar).func-fm, or main.Bar.func-fm.
+var methodRegexp = regexp.MustCompile(`(\w+)\.(\(\*)?(\w+)(\))?\.\w+\-fm$`)
+
+// Extract the type of the method value from its wrapper function name,
+// return the type named *main.Bar or main.Bar, in the previous cases.
+func extractTypeFromFunctionName(method string, p *Process) *Type {
+ if matches := methodRegexp.FindStringSubmatch(method); len(matches) == 5 {
+ var typeName string
+ if matches[2] == "(*" && matches[4] == ")" {
+ typeName = "*" + matches[1] + "." + matches[3]
+ } else {
+ typeName = matches[1] + "." + matches[3]
+ }
+ s := p.runtimeNameMap[typeName]
+ if len(s) > 0 {
+ // TODO: filter with the object size when there are multiple candidates.
+ return s[0]
+ }
+ }
+ return nil
+}
+
// typeObject takes an address and a type for the data at that address.
// For each pointer it finds in the memory at that address, it calls add with the pointer
// and the type + repeat count of the thing that it points to.
@@ -635,6 +659,12 @@
f.closure = ft
}
p.typeObject(closure, ft, r, add)
+ // handle the special case for method value.
+ // It's a single-entry closure laid out like {pc uintptr, x T}.
+ if typ := extractTypeFromFunctionName(f.name, p); typ != nil {
+ ptr := closure.Add(p.proc.PtrSize())
+ p.typeObject(ptr, typ, r, add)
+ }
case KindArray:
n := t.Elem.Size
for i := int64(0); i < t.Count; i++ {