diff --git a/_fixtures/break/break_amd64.s b/_fixtures/break/break_amd64.s new file mode 100644 index 00000000..a13eddc4 --- /dev/null +++ b/_fixtures/break/break_amd64.s @@ -0,0 +1,5 @@ +#include "textflag.h" + +TEXT ·asmBrk(SB),0,$0-0 + BYTE $0xcc + RET diff --git a/_fixtures/break/main.go b/_fixtures/break/main.go new file mode 100644 index 00000000..b0fd4426 --- /dev/null +++ b/_fixtures/break/main.go @@ -0,0 +1,7 @@ +package main + +func asmBrk() + +func main() { + asmBrk() +} diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index fd7b866c..8bf3f50c 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -2691,6 +2691,26 @@ func TestStepOutDeferReturnAndDirectCall(t *testing.T) { {contStepout, 28}}) } +func TestStepInstructionOnBreakpoint(t *testing.T) { + if runtime.GOARCH != "amd64" { + t.Skipf("skipping since not amd64") + } + // StepInstruction should step one instruction forward when + // PC is on a 1 byte instruction with a software breakpoint. + protest.AllowRecording(t) + withTestProcess("break/", t, func(p *proc.Target, fixture protest.Fixture) { + setFileBreakpoint(p, t, filepath.ToSlash(filepath.Join(fixture.BuildDir, "break_amd64.s")), 4) + + assertNoError(p.Continue(), t, "Continue()") + + pc := getRegisters(p, t).PC() + assertNoError(p.StepInstruction(), t, "StepInstruction()") + if pc == getRegisters(p, t).PC() { + t.Fatal("Could not step a single instruction") + } + }) +} + func TestStepOnCallPtrInstr(t *testing.T) { protest.AllowRecording(t) withTestProcess("teststepprog", t, func(p *proc.Target, fixture protest.Fixture) { diff --git a/pkg/proc/target_exec.go b/pkg/proc/target_exec.go index 78bf4e85..9a1a3185 100644 --- a/pkg/proc/target_exec.go +++ b/pkg/proc/target_exec.go @@ -433,7 +433,7 @@ func (grp *TargetGroup) StepInstruction() (err error) { return err } thread.Breakpoint().Clear() - err = thread.SetCurrentBreakpoint(true) + err = thread.SetCurrentBreakpoint(false) if err != nil { return err }