Skip to content

Commit

Permalink
proc: allow access to thread registers after a function call
Browse files Browse the repository at this point in the history
After a call injection sequence terminates allow the evaluator to
access thread registers again so that variables stored in registers can
be used as arguments.

Fixes go-delve#3310
  • Loading branch information
aarzilli committed Jan 22, 2025
1 parent d2f748f commit d550505
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
18 changes: 18 additions & 0 deletions _fixtures/issue3310.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

import (
"fmt"
"reflect"
)

var i = 2
var val = reflect.ValueOf(i)

func reflectFunc(value reflect.Value) {
fmt.Printf("%s\n", value.Type().Name())
}

func main() {
reflectFunc(val)
fmt.Println(&i)
}
14 changes: 14 additions & 0 deletions pkg/proc/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,20 @@ func (stack *evalStack) resume(g *G) {
}

// call injection protocol suspended or concluded, resume normal opcode execution
if len(stack.fncalls) == 0 && g.Thread != nil {
// The function call protocol concluded, recover the thread's registers so
// we can use them to evaluate variables.
so := scope.image()
if regs, err := g.Thread.Registers(); err == nil {
cfa := scope.Regs.CFA
frameBase := scope.Regs.FrameBase
dwarfRegs := *(scope.BinInfo.Arch.RegistersToDwarfRegisters(so.StaticBase, regs))
dwarfRegs.ChangeFunc = g.Thread.SetReg
scope.Regs = dwarfRegs
scope.Regs.CFA = cfa
scope.Regs.FrameBase = frameBase
}
}
stack.run()
}

Expand Down
12 changes: 12 additions & 0 deletions pkg/proc/variables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1946,3 +1946,15 @@ func TestClassicMap(t *testing.T) {
}
})
}

func TestCallFunctionRegisterArg(t *testing.T) {
protest.MustSupportFunctionCalls(t, testBackend)
if !goversion.VersionAfterOrEqual(runtime.Version(), 1, 23) {
t.Skip("not supported")
}
withTestProcessArgs("issue3310", t, ".", []string{}, protest.AllNonOptimized, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) {
setFileBreakpoint(p, t, fixture.Source, 12)
assertNoError(grp.Continue(), t, "Continue()")
assertNoError(proc.EvalExpressionWithCalls(grp, p.SelectedGoroutine(), "value.Type()", pnormalLoadConfig, true), t, "EvalExpressionWithCalls")
})
}

0 comments on commit d550505

Please sign in to comment.