From 34e802a42b9dc3ba3c4a513b50e9eec6afedcdf2 Mon Sep 17 00:00:00 2001 From: aarzilli Date: Mon, 3 Dec 2018 14:53:39 +0100 Subject: [PATCH] proc: make structMember work on pointer Variables created through cast When casting an integer into a struct pointer we make a fake pointer variable that doesn't have an address, maybeDereference and structMember should still work on this kind of Variable. Fixes #1432 --- _fixtures/issue1432.go | 16 ++++++++++++++++ pkg/proc/proc_test.go | 18 ++++++++++++++++++ pkg/proc/variables.go | 4 ++++ 3 files changed, 38 insertions(+) create mode 100644 _fixtures/issue1432.go diff --git a/_fixtures/issue1432.go b/_fixtures/issue1432.go new file mode 100644 index 00000000..cd1b49ef --- /dev/null +++ b/_fixtures/issue1432.go @@ -0,0 +1,16 @@ +package main + +import "runtime" + +type s struct { + i int64 +} + +func main() { + i := 1 + p := &i + s := s{i: 1} + _ = s + runtime.Breakpoint() + println(i, p) +} diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index b061d08b..c3adf297 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -4117,3 +4117,21 @@ func TestIssue1374(t *testing.T) { } }) } + +func TestIssue1432(t *testing.T) { + // Check that taking the address of a struct, casting it into a pointer to + // the struct's type and then accessing a member field will still: + // - perform auto-dereferencing on struct member access + // - yield a Variable that's ultimately assignable (i.e. has an address) + withTestProcess("issue1432", t, func(p proc.Process, fixture protest.Fixture) { + assertNoError(proc.Continue(p), t, "Continue") + svar := evalVariable(p, t, "s") + t.Logf("%#x", svar.Addr) + + scope, err := proc.GoroutineScope(p.CurrentThread()) + assertNoError(err, t, "GoroutineScope()") + + err = scope.SetVariable(fmt.Sprintf("(*\"main.s\")(%#x).i", svar.Addr), "10") + assertNoError(err, t, "SetVariable") + }) +} diff --git a/pkg/proc/variables.go b/pkg/proc/variables.go index 449703bc..ad3eedc1 100644 --- a/pkg/proc/variables.go +++ b/pkg/proc/variables.go @@ -932,6 +932,10 @@ func (v *Variable) maybeDereference() *Variable { switch t := v.RealType.(type) { case *godwarf.PtrType: + if v.Addr == 0 && len(v.Children) == 1 && v.loaded { + // fake pointer variable constructed by casting an integer to a pointer type + return &v.Children[0] + } ptrval, err := readUintRaw(v.mem, uintptr(v.Addr), t.ByteSize) r := v.newVariable("", uintptr(ptrval), t.Type, DereferenceMemory(v.mem)) if err != nil {