mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 18:57:18 +08:00 
			
		
		
		
	Remove timeoutWait due to improved scheduler handling
This commit is contained in:
		| @ -9,7 +9,6 @@ import ( | |||||||
| 	"os/exec" | 	"os/exec" | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"syscall" | 	"syscall" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"github.com/derekparker/delve/dwarf/frame" | 	"github.com/derekparker/delve/dwarf/frame" | ||||||
| 	"github.com/derekparker/delve/vendor/elf" | 	"github.com/derekparker/delve/vendor/elf" | ||||||
| @ -319,13 +318,9 @@ func (dbp *DebuggedProcess) Continue() error { | |||||||
| 	for _, thread := range dbp.Threads { | 	for _, thread := range dbp.Threads { | ||||||
| 		err := thread.Continue() | 		err := thread.Continue() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			// TODO(dp): There are some coordination issues |  | ||||||
| 			// here that need to be resolved. |  | ||||||
| 			if _, ok := err.(TimeoutError); !ok && err != syscall.ESRCH { |  | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	wpid, _, err := trapWait(dbp, -1, 0) | 	wpid, _, err := trapWait(dbp, -1, 0) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @ -558,57 +553,6 @@ type waitstats struct { | |||||||
| 	status *syscall.WaitStatus | 	status *syscall.WaitStatus | ||||||
| } | } | ||||||
|  |  | ||||||
| type TimeoutError struct { |  | ||||||
| 	pid int |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (err TimeoutError) Error() string { |  | ||||||
| 	return fmt.Sprintf("timeout waiting for %d", err.pid) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // TODO(dp): this is a hacky, racy implementation. Ideally this method will |  | ||||||
| // become defunct and replaced by a non-blocking incremental sleeping wait. |  | ||||||
| // The purpose is to detect whether a thread is sleeping. However, this is |  | ||||||
| // tricky because a thread can be sleeping due to being a blocked M in the |  | ||||||
| // scheduler or sleeping due to a user calling sleep. |  | ||||||
| func timeoutWait(thread *ThreadContext, options int) (int, *syscall.WaitStatus, error) { |  | ||||||
| 	var ( |  | ||||||
| 		statchan = make(chan *waitstats) |  | ||||||
| 		errchan  = make(chan error) |  | ||||||
| 	) |  | ||||||
|  |  | ||||||
| 	ps, err := parseProcessStatus(thread.Id) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return -1, nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if ps.state == STATUS_SLEEPING { |  | ||||||
| 		return 0, nil, nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	go func(pid int, statchan chan *waitstats, errchan chan error) { |  | ||||||
| 		wpid, status, err := wait(pid, 0) |  | ||||||
| 		if err != nil { |  | ||||||
| 			errchan <- fmt.Errorf("wait err %s %d", err, pid) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		statchan <- &waitstats{pid: wpid, status: status} |  | ||||||
| 	}(thread.Id, statchan, errchan) |  | ||||||
|  |  | ||||||
| 	select { |  | ||||||
| 	case s := <-statchan: |  | ||||||
| 		return s.pid, s.status, nil |  | ||||||
| 	case <-time.After(10 * time.Millisecond): |  | ||||||
| 		if err := syscall.Tgkill(thread.Process.Pid, thread.Id, syscall.SIGSTOP); err != nil { |  | ||||||
| 			return -1, nil, err |  | ||||||
| 		} |  | ||||||
| 		<-statchan |  | ||||||
| 		return 0, nil, TimeoutError{thread.Id} |  | ||||||
| 	case err := <-errchan: |  | ||||||
| 		return -1, nil, err |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func wait(pid, options int) (int, *syscall.WaitStatus, error) { | func wait(pid, options int) (int, *syscall.WaitStatus, error) { | ||||||
| 	var status syscall.WaitStatus | 	var status syscall.WaitStatus | ||||||
| 	wpid, err := syscall.Wait4(pid, &status, syscall.WALL|options, nil) | 	wpid, err := syscall.Wait4(pid, &status, syscall.WALL|options, nil) | ||||||
|  | |||||||
| @ -102,9 +102,7 @@ func TestBreakPoint(t *testing.T) { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		err = p.Step() | 		err = p.Step() | ||||||
| 		if _, ok := err.(proctl.TimeoutError); !ok { |  | ||||||
| 		assertNoError(err, t, "Step()") | 		assertNoError(err, t, "Step()") | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		pc, err = p.CurrentPC() | 		pc, err = p.CurrentPC() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
|  | |||||||
| @ -170,7 +170,7 @@ func (thread *ThreadContext) Step() (err error) { | |||||||
| 		return fmt.Errorf("step failed: %s", err.Error()) | 		return fmt.Errorf("step failed: %s", err.Error()) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	_, _, err = timeoutWait(thread, 0) | 	_, _, err = wait(thread.Id, 0) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Derek Parker
					Derek Parker