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
This commit is contained in:
parent
d7d4c144c8
commit
34e802a42b
16
_fixtures/issue1432.go
Normal file
16
_fixtures/issue1432.go
Normal file
@ -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)
|
||||||
|
}
|
@ -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")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -932,6 +932,10 @@ func (v *Variable) maybeDereference() *Variable {
|
|||||||
|
|
||||||
switch t := v.RealType.(type) {
|
switch t := v.RealType.(type) {
|
||||||
case *godwarf.PtrType:
|
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)
|
ptrval, err := readUintRaw(v.mem, uintptr(v.Addr), t.ByteSize)
|
||||||
r := v.newVariable("", uintptr(ptrval), t.Type, DereferenceMemory(v.mem))
|
r := v.newVariable("", uintptr(ptrval), t.Type, DereferenceMemory(v.mem))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user