Improve TestHalt reliability on Linux

This commit is contained in:
Derek Parker 2015-06-26 07:46:46 -05:00
parent 4f6c0de11f
commit db278d0453
6 changed files with 52 additions and 15 deletions

21
_fixtures/loopprog.go Normal file

@ -0,0 +1,21 @@
package main
import (
"fmt"
"time"
)
func loop() {
i := 0
for {
i++
fmt.Println(i)
time.Sleep(10 * time.Millisecond)
}
fmt.Println(i)
}
func main() {
fmt.Println("past main")
loop()
}

@ -362,7 +362,7 @@ func (dbp *Process) Continue() error {
for _, thread := range dbp.Threads {
err := thread.Continue()
if err != nil {
return err
return fmt.Errorf("could not continue thread %d %s", thread.Id, err)
}
}
return dbp.run(dbp.resume)

@ -239,6 +239,7 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
dbp.exited = true
return nil, ProcessExitedError{Pid: wpid, Status: status.ExitStatus()}
}
delete(dbp.Threads, wpid)
continue
}
if status.StopSignal() == sys.SIGTRAP && status.TrapCause() == sys.PTRACE_EVENT_CLONE {

@ -12,7 +12,8 @@ import (
)
func init() {
runtime.GOMAXPROCS(2)
runtime.GOMAXPROCS(4)
os.Setenv("GOMAXPROCS", "4")
}
func TestMain(m *testing.M) {
@ -57,7 +58,7 @@ func assertNoError(err error, t *testing.T, s string) {
if err != nil {
_, file, line, _ := runtime.Caller(1)
fname := filepath.Base(file)
t.Fatalf("failed assertion at %s:%d: %s : %s\n", fname, line, s, err)
t.Fatalf("failed assertion at %s:%d: %s - %s\n", fname, line, s, err)
}
}
@ -94,31 +95,40 @@ func TestExit(t *testing.T) {
}
func TestHalt(t *testing.T) {
runtime.GOMAXPROCS(2)
withTestProcess("testprog", t, func(p *Process, fixture protest.Fixture) {
stopChan := make(chan interface{})
withTestProcess("loopprog", t, func(p *Process, fixture protest.Fixture) {
_, err := p.SetBreakpointByLocation("main.loop")
assertNoError(err, t, "SetBreakpoint")
assertNoError(p.Continue(), t, "Continue")
for _, th := range p.Threads {
if th.running != false {
t.Fatal("expected running = false for thread", th.Id)
}
_, err := th.Registers()
assertNoError(err, t, "Registers")
}
go func() {
for {
if p.Running() {
err := p.RequestManualStop()
if err != nil {
if err := p.RequestManualStop(); err != nil {
t.Fatal(err)
}
stopChan <- nil
return
}
}
}()
err := p.Continue()
if err != nil {
t.Fatal(err)
}
assertNoError(p.Continue(), t, "Continue")
<-stopChan
// Loop through threads and make sure they are all
// actually stopped, err will not be nil if the process
// is still running.
for _, th := range p.Threads {
_, err := th.Registers()
if err != nil {
t.Error(err, th.Id)
if th.running != false {
t.Fatal("expected running = false for thread", th.Id)
}
_, err := th.Registers()
assertNoError(err, t, "Registers")
}
})
}

@ -86,7 +86,10 @@ func (thread *Thread) Step() (err error) {
// Restore breakpoint now that we have passed it.
defer func() {
var nbp *Breakpoint
nbp, err = thread.dbp.SetBreakpoint(bp.Addr)
nbp, err = thread.dbp.setBreakpoint(thread.Id, bp.Addr, bp.Temp)
if err != nil {
return
}
nbp.Temp = bp.Temp
}()
}

@ -35,6 +35,8 @@ func (t *Thread) resume() (err error) {
}
func (t *Thread) singleStep() (err error) {
t.running = true
defer func() { t.running = false }()
t.dbp.execPtraceFunc(func() { err = sys.PtraceSingleStep(t.Id) })
if err != nil {
return err