Fix Linux panic
This commit is contained in:
parent
450e5c4805
commit
27f68abebd
@ -5,9 +5,10 @@ import (
|
|||||||
"debug/gosym"
|
"debug/gosym"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
|
||||||
|
|
||||||
sys "golang.org/x/sys/unix"
|
sys "golang.org/x/sys/unix"
|
||||||
|
|
||||||
@ -103,20 +104,22 @@ func (dbp *DebuggedProcess) addThread(tid int, attach bool) (*ThreadContext, err
|
|||||||
Process: dbp,
|
Process: dbp,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if dbp.CurrentThread == nil {
|
||||||
|
dbp.CurrentThread = dbp.Threads[tid]
|
||||||
|
}
|
||||||
|
|
||||||
return dbp.Threads[tid], nil
|
return dbp.Threads[tid], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dbp *DebuggedProcess) updateThreadList() error {
|
func (dbp *DebuggedProcess) updateThreadList() error {
|
||||||
allm, err := dbp.CurrentThread.AllM()
|
tids, _ := filepath.Glob(fmt.Sprintf("/proc/%d/task/*", dbp.Pid))
|
||||||
if err != nil {
|
for _, tidpath := range tids {
|
||||||
return err
|
tidstr := filepath.Base(tidpath)
|
||||||
}
|
tid, err := strconv.Atoi(tidstr)
|
||||||
// TODO(dp) user /proc/<pid>/task to remove reliance on allm
|
if err != nil {
|
||||||
for _, m := range allm {
|
return err
|
||||||
if m.procid == 0 {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
if _, err := dbp.addThread(m.procid, false); err != nil {
|
if _, err := dbp.addThread(tid, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,27 +213,7 @@ func addNewThread(dbp *DebuggedProcess, cloner, cloned int) error {
|
|||||||
return fmt.Errorf("could not continue new thread %d %s", cloned, err)
|
return fmt.Errorf("could not continue new thread %d %s", cloned, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here we loop for a while to ensure that the once we continue
|
return dbp.Threads[cloner].Continue()
|
||||||
// the newly created thread, we allow enough time for the runtime
|
|
||||||
// to assign m->procid. This is important because we rely on
|
|
||||||
// looping through runtime.allm in other parts of the code, so
|
|
||||||
// we require that this is set before we do anything else.
|
|
||||||
// TODO(dp): we might be able to eliminate this loop by telling
|
|
||||||
// the CPU to emit a breakpoint exception on write to this location
|
|
||||||
// in memory. That way we prevent having to loop, and can be
|
|
||||||
// notified as soon as m->procid is set.
|
|
||||||
// TODO(dp) get rid of this hack
|
|
||||||
th = dbp.Threads[cloner]
|
|
||||||
for {
|
|
||||||
allm, _ := th.AllM()
|
|
||||||
for _, m := range allm {
|
|
||||||
if m.procid == cloned {
|
|
||||||
// Continue the thread that cloned
|
|
||||||
return th.Continue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
time.Sleep(time.Millisecond)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func stopped(pid int) bool {
|
func stopped(pid int) bool {
|
||||||
|
@ -107,7 +107,7 @@ func TestBreakPoint(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pc-1 != bp.Addr {
|
if pc-1 != bp.Addr && pc != bp.Addr {
|
||||||
f, l, _ := p.GoSymTable.PCToLine(pc)
|
f, l, _ := p.GoSymTable.PCToLine(pc)
|
||||||
t.Fatalf("Break not respected:\nPC:%#v %s:%d\nFN:%#v \n", pc, f, l, bp.Addr)
|
t.Fatalf("Break not respected:\nPC:%#v %s:%d\nFN:%#v \n", pc, f, l, bp.Addr)
|
||||||
}
|
}
|
||||||
|
@ -18,13 +18,14 @@ func (t *ThreadContext) Halt() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Halt err %s %d", err, t.Id)
|
return fmt.Errorf("Halt err %s %d", err, t.Id)
|
||||||
}
|
}
|
||||||
_, _, err = wait(t.Id, sys.WNOHANG)
|
_, _, err = wait(t.Id, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("wait err %s %d", err, t.Id)
|
return fmt.Errorf("wait err %s %d", err, t.Id)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(dp) rename this to resume or something
|
||||||
func (t *ThreadContext) cont() error {
|
func (t *ThreadContext) cont() error {
|
||||||
return PtraceCont(t.Id, 0)
|
return PtraceCont(t.Id, 0)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user