proc: make nested function calls work when stopped at a sw breakpoint (#2232)
evalFunctionCall needs to remove the breakpoint from the current thread after starting the function call injection, otherwise Continue will think that the thread is stopped at a breakpoint and return to the user instead of continuing the call injection.
This commit is contained in:
parent
807664b34b
commit
d3e9158e9e
@ -193,7 +193,7 @@ func main() {
|
||||
|
||||
d := &Derived{3, Base{4}}
|
||||
|
||||
runtime.Breakpoint()
|
||||
runtime.Breakpoint() // breakpoint here
|
||||
call1(one, two)
|
||||
fn2clos(2)
|
||||
strings.LastIndexByte(stringslice[1], 'w')
|
||||
|
||||
@ -316,6 +316,7 @@ func evalFunctionCall(scope *EvalScope, node *ast.CallExpr) (*Variable, error) {
|
||||
|
||||
fncallLog("function call initiated %v frame size %d goroutine %d (thread %d)", fncall.fn, fncall.argFrameSize, scope.g.ID, thread.ThreadID())
|
||||
|
||||
thread.Breakpoint().Clear() // since we moved address in PC the thread is no longer stopped at a breakpoint, leaving the breakpoint set will confuse Continue
|
||||
p.fncallForG[scope.g.ID].startThreadID = thread.ThreadID()
|
||||
|
||||
spoff := int64(scope.Regs.Uint64Val(scope.Regs.SPRegNum)) - int64(scope.g.stack.hi)
|
||||
@ -946,6 +947,10 @@ func isCallInjectionStop(t *Target, thread Thread, loc *Location) bool {
|
||||
if !strings.HasPrefix(loc.Fn.Name, debugCallFunctionNamePrefix1) && !strings.HasPrefix(loc.Fn.Name, debugCallFunctionNamePrefix2) {
|
||||
return false
|
||||
}
|
||||
if loc.PC == loc.Fn.Entry {
|
||||
// call injection just started, did not make any progress before being interrupted by a concurrent breakpoint.
|
||||
return false
|
||||
}
|
||||
text, err := disassembleCurrentInstruction(t, thread, -1)
|
||||
if err != nil || len(text) <= 0 {
|
||||
return false
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/constant"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sort"
|
||||
@ -1269,6 +1270,9 @@ func TestCallFunction(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Skip("function calls not supported on this version of go")
|
||||
}
|
||||
|
||||
testCallFunctionSetBreakpoint(t, p, fixture)
|
||||
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
for _, tc := range testcases {
|
||||
testCallFunction(t, p, tc)
|
||||
@ -1302,6 +1306,17 @@ func TestCallFunction(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func testCallFunctionSetBreakpoint(t *testing.T, p *proc.Target, fixture protest.Fixture) {
|
||||
buf, err := ioutil.ReadFile(fixture.Source)
|
||||
assertNoError(err, t, "ReadFile")
|
||||
for i, line := range strings.Split(string(buf), "\n") {
|
||||
if strings.Contains(line, "// breakpoint here") {
|
||||
setFileBreakpoint(p, t, fixture, i+1)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testCallFunction(t *testing.T, p *proc.Target, tc testCaseCallFunction) {
|
||||
const unsafePrefix = "-unsafe "
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user