Inject SIGTRAP for manual stop
Instead of fighting against the normal flow, just signal a SIGTRAP and let the existing flow handle it, as long as we set the halt flag correctly the system should halt.
This commit is contained in:
parent
8b68ae0bf5
commit
4d1dc5ad0e
@ -1,16 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
import "fmt"
|
||||
|
||||
func loop() {
|
||||
i := 0
|
||||
for {
|
||||
i++
|
||||
fmt.Println(i)
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
if (i % 100000) == 0 {
|
||||
fmt.Println(i)
|
||||
}
|
||||
}
|
||||
fmt.Println(i)
|
||||
}
|
||||
|
||||
23
proc/proc.go
23
proc/proc.go
@ -72,14 +72,6 @@ func New(pid int) *Process {
|
||||
return dbp
|
||||
}
|
||||
|
||||
// A ManualStopError happens when the user triggers a
|
||||
// manual stop via SIGERM.
|
||||
type ManualStopError struct{}
|
||||
|
||||
func (mse ManualStopError) Error() string {
|
||||
return "Manual stop requested"
|
||||
}
|
||||
|
||||
// ProcessExitedError indicates that the process has exited and contains both
|
||||
// process id and exit status.
|
||||
type ProcessExitedError struct {
|
||||
@ -208,15 +200,7 @@ func (dbp *Process) FindLocation(str string) (uint64, error) {
|
||||
// execution. Sends SIGSTOP to all threads.
|
||||
func (dbp *Process) RequestManualStop() error {
|
||||
dbp.halt = true
|
||||
err := dbp.requestManualStop()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = dbp.Halt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return dbp.requestManualStop()
|
||||
}
|
||||
|
||||
// Sets a breakpoint at addr, and stores it in the process wide
|
||||
@ -668,14 +652,11 @@ func (dbp *Process) run(fn func() error) error {
|
||||
if dbp.exited {
|
||||
return fmt.Errorf("process has already exited")
|
||||
}
|
||||
dbp.halt = false
|
||||
for _, th := range dbp.Threads {
|
||||
th.CurrentBreakpoint = nil
|
||||
}
|
||||
if err := fn(); err != nil {
|
||||
if _, ok := err.(ManualStopError); !ok {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -250,7 +250,7 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
|
||||
// process natural death _sometimes_.
|
||||
continue
|
||||
}
|
||||
return nil, ManualStopError{}
|
||||
return nil, nil
|
||||
case 0:
|
||||
return nil, fmt.Errorf("error while waiting for task")
|
||||
}
|
||||
@ -261,6 +261,10 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
|
||||
th, err = dbp.handleBreakpointOnThread(int(port))
|
||||
if err != nil {
|
||||
if _, ok := err.(NoBreakpointError); ok {
|
||||
if dbp.halt {
|
||||
dbp.halt = false
|
||||
return dbp.Threads[int(port)], nil
|
||||
}
|
||||
th := dbp.Threads[int(port)]
|
||||
if dbp.firstStart || dbp.singleStepping || th.singleStepping {
|
||||
dbp.firstStart = false
|
||||
|
||||
@ -57,7 +57,7 @@ func Launch(cmd []string) (*Process, error) {
|
||||
}
|
||||
|
||||
func (dbp *Process) requestManualStop() (err error) {
|
||||
return sys.Kill(dbp.Pid, sys.SIGSTOP)
|
||||
return sys.Kill(dbp.Pid, sys.SIGTRAP)
|
||||
}
|
||||
|
||||
// Attach to a newly created thread, and store that thread in our list of
|
||||
@ -277,18 +277,15 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
|
||||
// Sometimes we get an unknown thread, ignore it?
|
||||
continue
|
||||
}
|
||||
if status.StopSignal() == sys.SIGTRAP && dbp.halt {
|
||||
th.running = false
|
||||
dbp.halt = false
|
||||
return th, nil
|
||||
}
|
||||
if status.StopSignal() == sys.SIGTRAP {
|
||||
th.running = false
|
||||
return dbp.handleBreakpointOnThread(wpid)
|
||||
}
|
||||
if status.StopSignal() == sys.SIGTRAP && dbp.halt {
|
||||
th.running = false
|
||||
return th, nil
|
||||
}
|
||||
if status.StopSignal() == sys.SIGSTOP && dbp.halt {
|
||||
th.running = false
|
||||
return nil, ManualStopError{}
|
||||
}
|
||||
if th != nil {
|
||||
// TODO(dp) alert user about unexpected signals here.
|
||||
if err := th.Continue(); err != nil {
|
||||
|
||||
@ -7,7 +7,6 @@ import (
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
protest "github.com/derekparker/delve/proc/test"
|
||||
)
|
||||
@ -111,7 +110,6 @@ func TestHalt(t *testing.T) {
|
||||
go func() {
|
||||
for {
|
||||
if p.Running() {
|
||||
time.Sleep(time.Millisecond)
|
||||
if err := p.RequestManualStop(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user