From 5f0f77f4144f473b9b5d63e626c0f427ab194849 Mon Sep 17 00:00:00 2001 From: aarzilli Date: Thu, 26 Oct 2017 18:08:01 +0200 Subject: [PATCH] proc: automatically dereference interfaces on member access If 'iv' is an interface variable with a struct as a concrete value let 'iv.A' evaluate to the access to field 'A' of the concrete value of 'iv'. --- pkg/proc/variables.go | 5 +++++ service/test/variables_test.go | 2 ++ 2 files changed, 7 insertions(+) diff --git a/pkg/proc/variables.go b/pkg/proc/variables.go index aec9b4cb..a30a4838 100644 --- a/pkg/proc/variables.go +++ b/pkg/proc/variables.go @@ -670,6 +670,11 @@ func (v *Variable) structMember(memberName string) (*Variable, error) { case reflect.Chan: v = v.clone() v.RealType = resolveTypedef(&(v.RealType.(*godwarf.ChanType).TypedefType)) + case reflect.Interface: + v.loadInterface(0, false, LoadConfig{}) + if len(v.Children) > 0 { + v = &v.Children[0] + } } structVar := v.maybeDereference() structVar.Name = v.Name diff --git a/service/test/variables_test.go b/service/test/variables_test.go index b90973b3..45e6a31c 100644 --- a/service/test/variables_test.go +++ b/service/test/variables_test.go @@ -552,6 +552,8 @@ func TestEvalExpression(t *testing.T) { {"err2", true, "error(*main.bstruct) *{a: main.astruct {A: 1, B: 2}}", "error(*main.bstruct) 0x…", "error", nil}, {"errnil", true, "error nil", "error nil", "error", nil}, {"iface1", true, "interface {}(*main.astruct) *{A: 1, B: 2}", "interface {}(*main.astruct) 0x…", "interface {}", nil}, + {"iface1.A", false, "1", "1", "int", nil}, + {"iface1.B", false, "2", "2", "int", nil}, {"iface2", true, "interface {}(string) \"test\"", "interface {}(string) \"test\"", "interface {}", nil}, {"iface3", true, "interface {}(map[string]go/constant.Value) []", "interface {}(map[string]go/constant.Value) []", "interface {}", nil}, {"iface4", true, "interface {}([]go/constant.Value) [4]", "interface {}([]go/constant.Value) [...]", "interface {}", nil},