Skip to content

Commit

Permalink
internal/gocore: extract type name of method value from its wrapper f…
Browse files Browse the repository at this point in the history
…unction 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: 06c4faf
GitHub-Pull-Request: #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>
  • Loading branch information
doujiang24 authored and randall77 committed Aug 15, 2022
1 parent 8ea6c74 commit f98d67a
Showing 1 changed file with 30 additions and 0 deletions.
30 changes: 30 additions & 0 deletions internal/gocore/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package gocore

import (
"fmt"
"regexp"
"strings"

"golang.org/x/debug/internal/core"
Expand Down Expand Up @@ -545,6 +546,29 @@ func (fr *frameReader) ReadInt(a core.Address) int64 {
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.
Expand Down Expand Up @@ -635,6 +659,12 @@ func (p *Process) typeObject(a core.Address, t *Type, r reader, add func(core.Ad
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++ {
Expand Down

0 comments on commit f98d67a

Please sign in to comment.