提交 5c2673a6 编写于 作者: A aarzilli 提交者: Derek Parker

proc/native, proc/gdbserial: StepInstruction without goroutine

proc.Process.StepInstruction should work even if there is no goroutine
selected.
上级 e9e08300
......@@ -623,25 +623,26 @@ continueLoop:
}
func (p *Process) StepInstruction() error {
if p.selectedGoroutine == nil {
return errors.New("cannot single step: no selected goroutine")
}
if p.selectedGoroutine.Thread == nil {
if _, err := p.SetBreakpoint(p.selectedGoroutine.PC, proc.NextBreakpoint, proc.SameGoroutineCondition(p.selectedGoroutine)); err != nil {
return err
thread := p.currentThread
if p.selectedGoroutine != nil {
if p.selectedGoroutine.Thread == nil {
if _, err := p.SetBreakpoint(p.selectedGoroutine.PC, proc.NextBreakpoint, proc.SameGoroutineCondition(p.selectedGoroutine)); err != nil {
return err
}
return proc.Continue(p)
}
return proc.Continue(p)
thread = p.selectedGoroutine.Thread.(*Thread)
}
p.allGCache = nil
if p.exited {
return &proc.ProcessExitedError{Pid: p.conn.pid}
}
p.selectedGoroutine.Thread.(*Thread).clearBreakpointState()
err := p.selectedGoroutine.Thread.(*Thread).StepInstruction()
thread.clearBreakpointState()
err := thread.StepInstruction()
if err != nil {
return err
}
return p.selectedGoroutine.Thread.(*Thread).SetCurrentBreakpoint()
return thread.SetCurrentBreakpoint()
}
func (p *Process) SwitchThread(tid int) error {
......
package native
import (
"errors"
"fmt"
"go/ast"
"os"
......@@ -297,26 +296,27 @@ func (dbp *Process) ContinueOnce() (proc.Thread, error) {
// asssociated with the selected goroutine. All other
// threads will remain stopped.
func (dbp *Process) StepInstruction() (err error) {
if dbp.selectedGoroutine == nil {
return errors.New("cannot single step: no selected goroutine")
}
if dbp.selectedGoroutine.Thread == nil {
// Step called on parked goroutine
if _, err := dbp.SetBreakpoint(dbp.selectedGoroutine.PC, proc.NextBreakpoint, proc.SameGoroutineCondition(dbp.selectedGoroutine)); err != nil {
return err
thread := dbp.currentThread
if dbp.selectedGoroutine != nil {
if dbp.selectedGoroutine.Thread == nil {
// Step called on parked goroutine
if _, err := dbp.SetBreakpoint(dbp.selectedGoroutine.PC, proc.NextBreakpoint, proc.SameGoroutineCondition(dbp.selectedGoroutine)); err != nil {
return err
}
return proc.Continue(dbp)
}
return proc.Continue(dbp)
thread = dbp.selectedGoroutine.Thread.(*Thread)
}
dbp.allGCache = nil
if dbp.exited {
return &proc.ProcessExitedError{}
}
dbp.selectedGoroutine.Thread.(*Thread).clearBreakpointState()
err = dbp.selectedGoroutine.Thread.(*Thread).StepInstruction()
thread.clearBreakpointState()
err = thread.StepInstruction()
if err != nil {
return err
}
return dbp.selectedGoroutine.Thread.(*Thread).SetCurrentBreakpoint()
return thread.SetCurrentBreakpoint()
}
// SwitchThread changes from current thread to the thread specified by `tid`.
......
......@@ -19,6 +19,7 @@ import (
"testing"
"time"
"github.com/derekparker/delve/pkg/dwarf/frame"
"github.com/derekparker/delve/pkg/proc"
"github.com/derekparker/delve/pkg/proc/gdbserial"
"github.com/derekparker/delve/pkg/proc/native"
......@@ -2954,3 +2955,29 @@ func TestIssue877(t *testing.T) {
}
})
}
func TestIssue893(t *testing.T) {
// Test what happens when next is called immediately after launching the
// executable, acceptable behaviors are: (a) no error, (b) no source at PC
// error.
protest.AllowRecording(t)
withTestProcess("increment", t, func(p proc.Process, fixture protest.Fixture) {
err := proc.Next(p)
if err == nil {
return
}
if _, ok := err.(*frame.NoFDEForPCError); ok {
return
}
assertNoError(err, t, "Next")
})
}
func TestStepInstructionNoGoroutine(t *testing.T) {
protest.AllowRecording(t)
withTestProcess("increment", t, func(p proc.Process, fixture protest.Fixture) {
// Call StepInstruction immediately after launching the program, it should
// work even though no goroutine is selected.
assertNoError(p.StepInstruction(), t, "StepInstruction")
})
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册