Skip to content

Wrong anonymous method shown when local var name matches package name #4179

@wenxuan70

Description

@wenxuan70

If a local variable shares the same name as a package, and that variable’s field points to a struct from that package, dlv p ends up showing an incorrect anonymous method generated by the Go compiler.

Looks like the name resolver inside Delve gets confused between the package and the variable scope.

Minimal reproducible example:

config/test.go

package config

type Test struct {
	Name interface{}
	Age  int
}

main.go

package main

import (
	"log"
	"wenxuan70/config"
)

type Config struct {
	*config.Test
}

func f() *config.Test {
	return &config.Test{}
}

func main() {
	config := &Config{}

	config.Test = f()

	log.Printf("%+#v", config)
}
Image

The problem comes from this line:

if fn.Name == name || strings.HasSuffix(fn.Name, "/"+name) {

We could probably skip methods prefixed with type:.eq. — they’re compiler-generated and not meant to be visible to users anyway.
Here’s a small patch I tested locally that fixes it.

diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go
index 609022c0..cb0e91a7 100644
--- a/pkg/proc/eval.go
+++ b/pkg/proc/eval.go
@@ -822,7 +822,7 @@ func (scope *EvalScope) findGlobalInternal(name string) (*Variable, error) {
 		}
 	}
 	for _, fn := range scope.BinInfo.Functions {
-		if fn.Name == name || strings.HasSuffix(fn.Name, "/"+name) {
+		if fn.Name == name || (strings.HasSuffix(fn.Name, "/"+name) && !strings.HasPrefix(fn.Name, "type:.eq.")) {
 			//TODO(aarzilli): convert function entry into a function type?
 			r := newVariable(fn.Name, fn.Entry, &godwarf.FuncType{}, scope.BinInfo, scope.Mem)
 			r.Value = constant.MakeString(fn.Name)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions