proc: Continue does not work with breakpoints set on NOP (OSX)
Fixes #262
This commit is contained in:
parent
708cf2f290
commit
b21686e6c4
@ -11,7 +11,7 @@ func demo(id int, wait *sync.WaitGroup) {
|
||||
for i := 0; i < 100; i++ {
|
||||
sleep := rand.Intn(10) + 1
|
||||
fmt.Printf("id: %d step: %d sleeping %d\n", id, i, sleep)
|
||||
time.Sleep(time.Duration(sleep) * time.Millisecond)
|
||||
time.Sleep(time.Duration(sleep) * time.Millisecond)
|
||||
}
|
||||
|
||||
wait.Done()
|
||||
|
16
_fixtures/issue262.go
Normal file
16
_fixtures/issue262.go
Normal file
@ -0,0 +1,16 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func typicalFunction() (res int) {
|
||||
defer func() {
|
||||
res = 2
|
||||
return
|
||||
}()
|
||||
res = 10
|
||||
return // setup breakpoint here
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println(typicalFunction())
|
||||
}
|
@ -329,5 +329,13 @@ func (dbp *Process) wait(pid, options int) (int, *sys.WaitStatus, error) {
|
||||
}
|
||||
|
||||
func (dbp *Process) exitGuard(err error) error {
|
||||
if err != ErrContinueThread {
|
||||
return err
|
||||
}
|
||||
_, status, werr := dbp.wait(dbp.Pid, sys.WNOHANG)
|
||||
if werr == nil && status.Exited() {
|
||||
dbp.postExit()
|
||||
return ProcessExitedError{Pid: dbp.Pid, Status: status.ExitStatus()}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -953,7 +953,7 @@ func TestFrameEvaluation(t *testing.T) {
|
||||
assertNoError(err, t, "setFunctionBreakpoint")
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
|
||||
/**** Testing evaluation on goroutines ****/
|
||||
// Testing evaluation on goroutines
|
||||
gs, err := p.GoroutinesInfo()
|
||||
assertNoError(err, t, "GoroutinesInfo")
|
||||
found := make([]bool, 10)
|
||||
@ -992,7 +992,7 @@ func TestFrameEvaluation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
/**** Testing evaluation on frames ****/
|
||||
// Testing evaluation on frames
|
||||
assertNoError(p.Continue(), t, "Continue() 2")
|
||||
g, err := p.CurrentThread.GetG()
|
||||
assertNoError(err, t, "GetG()")
|
||||
@ -1129,3 +1129,23 @@ func TestBreakpointCounts(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestIssue262(t *testing.T) {
|
||||
// Continue does not work when the current breakpoint is set on a NOP instruction
|
||||
withTestProcess("issue262", t, func(p *Process, fixture protest.Fixture) {
|
||||
addr, _, err := p.goSymTable.LineToPC(fixture.Source, 11)
|
||||
assertNoError(err, t, "LineToPC")
|
||||
_, err = p.SetBreakpoint(addr)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
err = p.Continue()
|
||||
if err == nil {
|
||||
t.Fatalf("No error on second continue")
|
||||
}
|
||||
_, exited := err.(ProcessExitedError)
|
||||
if !exited {
|
||||
t.Fatalf("Process did not exit after second continue: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package proc
|
||||
|
||||
// #include "threads_darwin.h"
|
||||
// #include "proc_darwin.h"
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
@ -12,6 +13,8 @@ type OSSpecificDetails struct {
|
||||
registers C.x86_thread_state64_t
|
||||
}
|
||||
|
||||
var ErrContinueThread = fmt.Errorf("could not continue thread")
|
||||
|
||||
func (t *Thread) halt() (err error) {
|
||||
kret := C.thread_suspend(t.os.thread_act)
|
||||
if kret != C.KERN_SUCCESS {
|
||||
@ -27,7 +30,13 @@ func (t *Thread) singleStep() error {
|
||||
if kret != C.KERN_SUCCESS {
|
||||
return fmt.Errorf("could not single step")
|
||||
}
|
||||
t.dbp.trapWait(0)
|
||||
for {
|
||||
port := C.mach_port_wait(t.dbp.os.portSet)
|
||||
if port == C.mach_port_t(t.Id) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
kret = C.clear_trap_flag(t.os.thread_act)
|
||||
if kret != C.KERN_SUCCESS {
|
||||
return fmt.Errorf("could not clear CPU trap flag")
|
||||
@ -45,7 +54,7 @@ func (t *Thread) resume() error {
|
||||
}
|
||||
kret := C.resume_thread(t.os.thread_act)
|
||||
if kret != C.KERN_SUCCESS {
|
||||
return fmt.Errorf("could not continue thread")
|
||||
return ErrContinueThread
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user