diff --git a/README.md b/README.md index 658e8dd25c06e64f74bd8012ae79d84877e92619..a639fbee0fb0ff4857ce8b8cd9722cf45e267c8a 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,8 @@ Once inside a debugging session, the following commands may be used: * `threads` - Print status of all traced threads. +* `thread $tid` - Switch to another thread. + * `goroutines` - Print status of all goroutines. * `breakpoints` - Print information on all active breakpoints. diff --git a/command/command.go b/command/command.go index 5246fe32a77b1170b6e2c128b9f41a445fc736b8..684ffcad0fd573eb88a4445d81c3cd05bdae7a66 100644 --- a/command/command.go +++ b/command/command.go @@ -9,6 +9,7 @@ import ( "os" "regexp" "sort" + "strconv" "strings" "github.com/derekparker/delve/proctl" @@ -48,6 +49,7 @@ func DebugCommands() *Commands { command{aliases: []string{"step", "si"}, cmdFn: step, helpMsg: "Single step through program."}, command{aliases: []string{"next", "n"}, cmdFn: next, helpMsg: "Step over to next source line."}, command{aliases: []string{"threads"}, cmdFn: threads, helpMsg: "Print out info for every traced thread."}, + command{aliases: []string{"thread", "t"}, cmdFn: thread, helpMsg: "Switch to the specified thread."}, command{aliases: []string{"clear"}, cmdFn: clear, helpMsg: "Deletes breakpoint."}, command{aliases: []string{"goroutines"}, cmdFn: goroutines, helpMsg: "Print out info for every goroutine."}, command{aliases: []string{"breakpoints", "bp"}, cmdFn: breakpoints, helpMsg: "Print out info for active breakpoints."}, @@ -136,6 +138,22 @@ func threads(p *proctl.DebuggedProcess, ars ...string) error { return nil } +func thread(p *proctl.DebuggedProcess, ars ...string) error { + oldTid := p.CurrentThread.Id + tid, err := strconv.Atoi(ars[0]) + if err != nil { + return err + } + + err = p.SwitchThread(tid) + if err != nil { + return err + } + + fmt.Printf("Switched from %d to %d\n", oldTid, tid) + return nil +} + func goroutines(p *proctl.DebuggedProcess, ars ...string) error { return p.PrintGoroutinesInfo() } diff --git a/proctl/proctl.go b/proctl/proctl.go index d8a2e8d118aa87e8da19a96db52a3c71f38c4af2..6ec83531eb41cc7fbbb6e63ffae55862b6551862 100644 --- a/proctl/proctl.go +++ b/proctl/proctl.go @@ -311,12 +311,22 @@ func (dbp *DebuggedProcess) Step() (err error) { return dbp.run(fn) } +// Change from current thread to the thread specified by `tid`. +func (dbp *DebuggedProcess) SwitchThread(tid int) error { + if th, ok := dbp.Threads[tid]; ok { + dbp.CurrentThread = th + return nil + } + return fmt.Errorf("thread %d does not exist", tid) +} + // Obtains register values from what Delve considers to be the current // thread of the traced process. func (dbp *DebuggedProcess) Registers() (Registers, error) { return dbp.CurrentThread.Registers() } +// Returns the PC of the current thread. func (dbp *DebuggedProcess) CurrentPC() (uint64, error) { return dbp.CurrentThread.CurrentPC() }