提交 6c973bf2 编写于 作者: A aarzilli 提交者: Derek Parker

proc/native: move halt to os specific struct

The windows backend isn't using the halt field so it can be removed
there.
On linux it can be replaced with a parameter passed to trapWait.
上级 8561db8c
......@@ -32,8 +32,7 @@ type Process struct {
allGCache []*proc.G
os *OSProcessDetails
firstStart bool
haltMu sync.Mutex
halt bool
stopMu sync.Mutex
resumeChan chan<- struct{}
exited bool
ptraceChan chan func()
......@@ -176,18 +175,17 @@ func (dbp *Process) RequestManualStop() error {
if dbp.exited {
return &proc.ProcessExitedError{Pid: dbp.Pid()}
}
dbp.haltMu.Lock()
defer dbp.haltMu.Unlock()
dbp.stopMu.Lock()
defer dbp.stopMu.Unlock()
dbp.manualStopRequested = true
dbp.halt = true
return dbp.requestManualStop()
}
func (dbp *Process) CheckAndClearManualStopRequest() bool {
dbp.haltMu.Lock()
dbp.stopMu.Lock()
msr := dbp.manualStopRequested
dbp.manualStopRequested = false
dbp.haltMu.Unlock()
dbp.stopMu.Unlock()
return msr
}
......
......@@ -25,6 +25,7 @@ type OSProcessDetails struct {
exceptionPort C.mach_port_t // mach port for receiving mach exceptions.
notificationPort C.mach_port_t // mach port for dead name notification (process exit).
initialized bool
halt bool
// the main port we use, will return messages from both the
// exception and notification ports.
......@@ -191,6 +192,7 @@ func (dbp *Process) requestManualStop() (err error) {
thread = C.mach_port_t(dbp.currentThread.os.threadAct)
exceptionPort = C.mach_port_t(dbp.os.exceptionPort)
)
dbp.os.halt = true
kret := C.raise_exception(task, thread, exceptionPort, C.EXC_BREAKPOINT)
if kret != C.KERN_SUCCESS {
return fmt.Errorf("could not raise mach exception")
......@@ -306,9 +308,9 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
return nil, proc.ProcessExitedError{Pid: dbp.pid, Status: status.ExitStatus()}
case C.MACH_RCV_INTERRUPTED:
dbp.haltMu.Lock()
halt := dbp.halt
dbp.haltMu.Unlock()
dbp.stopMu.Lock()
halt := dbp.os.halt
dbp.stopMu.Unlock()
if !halt {
// Call trapWait again, it seems
// MACH_RCV_INTERRUPTED is emitted before
......@@ -337,11 +339,11 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
dbp.updateThreadList()
th, ok := dbp.threads[int(port)]
if !ok {
dbp.haltMu.Lock()
halt := dbp.halt
dbp.haltMu.Unlock()
dbp.stopMu.Lock()
halt := dbp.os.halt
dbp.stopMu.Unlock()
if halt {
dbp.halt = false
dbp.os.halt = false
return th, nil
}
if dbp.firstStart || th.singleStepping {
......@@ -424,14 +426,14 @@ func (dbp *Process) resume() error {
return nil
}
// stop stops all running threads threads and sets breakpoints
// stop stops all running threads and sets breakpoints
func (dbp *Process) stop(trapthread *Thread) (err error) {
if dbp.exited {
return &proc.ProcessExitedError{Pid: dbp.Pid()}
}
for _, th := range dbp.threads {
if !th.Stopped() {
if err := th.halt(); err != nil {
if err := th.stop(); err != nil {
return dbp.exitGuard(err)
}
}
......
......@@ -194,6 +194,10 @@ func findExecutable(path string, pid int) string {
}
func (dbp *Process) trapWait(pid int) (*Thread, error) {
return dbp.trapWaitInternal(pid, false)
}
func (dbp *Process) trapWaitInternal(pid int, halt bool) (*Thread, error) {
for {
wpid, status, err := dbp.wait(pid, 0)
if err != nil {
......@@ -235,11 +239,7 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
}
return nil, err
}
dbp.haltMu.Lock()
halt := dbp.halt
dbp.haltMu.Unlock()
if halt {
dbp.halt = false
th.os.running = false
dbp.threads[int(wpid)].os.running = false
return nil, nil
......@@ -263,15 +263,7 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
// Sometimes we get an unknown thread, ignore it?
continue
}
dbp.haltMu.Lock()
halt := dbp.halt
dbp.haltMu.Unlock()
if halt && (status.StopSignal() == sys.SIGTRAP || status.StopSignal() == sys.SIGSTOP) {
th.os.running = false
dbp.halt = false
return th, nil
}
if status.StopSignal() == sys.SIGTRAP {
if (halt && status.StopSignal() == sys.SIGSTOP) || (status.StopSignal() == sys.SIGTRAP) {
th.os.running = false
return th, nil
}
......@@ -382,7 +374,7 @@ func (dbp *Process) exitGuard(err error) error {
return err
}
if status(dbp.pid, dbp.os.comm) == StatusZombie {
_, err := dbp.trapWait(-1)
_, err := dbp.trapWaitInternal(-1, false)
return err
}
......@@ -415,7 +407,7 @@ func (dbp *Process) stop(trapthread *Thread) (err error) {
}
for _, th := range dbp.threads {
if !th.Stopped() {
if err := th.halt(); err != nil {
if err := th.stop(); err != nil {
return dbp.exitGuard(err)
}
}
......@@ -433,8 +425,7 @@ func (dbp *Process) stop(trapthread *Thread) (err error) {
if allstopped {
break
}
dbp.halt = true
_, err := dbp.trapWait(-1)
_, err := dbp.trapWaitInternal(-1, true)
if err != nil {
return err
}
......
......@@ -27,7 +27,7 @@ type OSSpecificDetails struct {
// be continued.
var ErrContinueThread = fmt.Errorf("could not continue thread")
func (t *Thread) halt() (err error) {
func (t *Thread) stop() (err error) {
kret := C.thread_suspend(t.os.threadAct)
if kret != C.KERN_SUCCESS {
errStr := C.GoString(C.mach_error_string(C.mach_error_t(kret)))
......
......@@ -17,10 +17,10 @@ type OSSpecificDetails struct {
running bool
}
func (t *Thread) halt() (err error) {
func (t *Thread) stop() (err error) {
err = sys.Tgkill(t.dbp.pid, t.ID, sys.SIGSTOP)
if err != nil {
err = fmt.Errorf("halt err %s on thread %d", err, t.ID)
err = fmt.Errorf("stop err %s on thread %d", err, t.ID)
return
}
return
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册