terminal,service: print WaitReason, WaitSince for goroutines (#2270)
Fixes #637
This commit is contained in:
parent
433eafb280
commit
6d1c00e56d
@ -322,9 +322,7 @@ func TestRedirect(t *testing.T) {
|
|||||||
|
|
||||||
// and detach from and kill the headless instance
|
// and detach from and kill the headless instance
|
||||||
client := rpc2.NewClient(listenAddr)
|
client := rpc2.NewClient(listenAddr)
|
||||||
if err := client.Detach(true); err != nil {
|
_ = client.Detach(true)
|
||||||
t.Fatalf("error detaching from headless instance: %v", err)
|
|
||||||
}
|
|
||||||
cmd.Wait()
|
cmd.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/cosiner/argv"
|
"github.com/cosiner/argv"
|
||||||
"github.com/go-delve/delve/pkg/locspec"
|
"github.com/go-delve/delve/pkg/locspec"
|
||||||
@ -922,11 +923,58 @@ func (t *Term) formatGoroutine(g *api.Goroutine, fgl formatGoroutineLoc) string
|
|||||||
locname = "Start"
|
locname = "Start"
|
||||||
loc = g.StartLoc
|
loc = g.StartLoc
|
||||||
}
|
}
|
||||||
thread := ""
|
|
||||||
|
buf := new(strings.Builder)
|
||||||
|
fmt.Fprintf(buf, "%d - %s: %s", g.ID, locname, t.formatLocation(loc))
|
||||||
if g.ThreadID != 0 {
|
if g.ThreadID != 0 {
|
||||||
thread = fmt.Sprintf(" (thread %d)", g.ThreadID)
|
fmt.Fprintf(buf, " (thread %d)", g.ThreadID)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%d - %s: %s%s", g.ID, locname, t.formatLocation(loc), thread)
|
|
||||||
|
if (g.Status == api.GoroutineWaiting || g.Status == api.GoroutineSyscall) && g.WaitReason != 0 {
|
||||||
|
var wr string
|
||||||
|
if g.WaitReason > 0 && g.WaitReason < int64(len(waitReasonStrings)) {
|
||||||
|
wr = waitReasonStrings[g.WaitReason]
|
||||||
|
} else {
|
||||||
|
wr = fmt.Sprintf("unknown wait reason %d", g.WaitReason)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(buf, " [%s", wr)
|
||||||
|
if g.WaitSince > 0 {
|
||||||
|
fmt.Fprintf(buf, " %s", time.Since(time.Unix(0, g.WaitSince)).String())
|
||||||
|
}
|
||||||
|
fmt.Fprintf(buf, "]")
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
var waitReasonStrings = [...]string{
|
||||||
|
"",
|
||||||
|
"GC assist marking",
|
||||||
|
"IO wait",
|
||||||
|
"chan receive (nil chan)",
|
||||||
|
"chan send (nil chan)",
|
||||||
|
"dumping heap",
|
||||||
|
"garbage collection",
|
||||||
|
"garbage collection scan",
|
||||||
|
"panicwait",
|
||||||
|
"select",
|
||||||
|
"select (no cases)",
|
||||||
|
"GC assist wait",
|
||||||
|
"GC sweep wait",
|
||||||
|
"GC scavenge wait",
|
||||||
|
"chan receive",
|
||||||
|
"chan send",
|
||||||
|
"finalizer wait",
|
||||||
|
"force gc (idle)",
|
||||||
|
"semacquire",
|
||||||
|
"sleep",
|
||||||
|
"sync.Cond.Wait",
|
||||||
|
"timer goroutine (idle)",
|
||||||
|
"trace reader (blocked)",
|
||||||
|
"wait for GC cycle",
|
||||||
|
"GC worker (idle)",
|
||||||
|
"preempted",
|
||||||
|
"debug call",
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeGoroutineLong(t *Term, w io.Writer, g *api.Goroutine, prefix string) {
|
func writeGoroutineLong(t *Term, w io.Writer, g *api.Goroutine, prefix string) {
|
||||||
|
|||||||
@ -298,6 +298,7 @@ func ConvertGoroutine(g *proc.G) *Goroutine {
|
|||||||
WaitSince: g.WaitSince,
|
WaitSince: g.WaitSince,
|
||||||
WaitReason: g.WaitReason,
|
WaitReason: g.WaitReason,
|
||||||
Labels: g.Labels(),
|
Labels: g.Labels(),
|
||||||
|
Status: g.Status,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -314,6 +314,7 @@ type Goroutine struct {
|
|||||||
StartLoc Location `json:"startLoc"`
|
StartLoc Location `json:"startLoc"`
|
||||||
// ID of the associated thread for running goroutines
|
// ID of the associated thread for running goroutines
|
||||||
ThreadID int `json:"threadID"`
|
ThreadID int `json:"threadID"`
|
||||||
|
Status uint64 `json:"status"`
|
||||||
WaitSince int64 `json:"waitSince"`
|
WaitSince int64 `json:"waitSince"`
|
||||||
WaitReason int64 `json:"waitReason"`
|
WaitReason int64 `json:"waitReason"`
|
||||||
Unreadable string `json:"unreadable"`
|
Unreadable string `json:"unreadable"`
|
||||||
@ -321,6 +322,11 @@ type Goroutine struct {
|
|||||||
Labels map[string]string `json:"labels,omitempty"`
|
Labels map[string]string `json:"labels,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
GoroutineWaiting = proc.Gwaiting
|
||||||
|
GoroutineSyscall = proc.Gsyscall
|
||||||
|
)
|
||||||
|
|
||||||
// DebuggerCommand is a command which changes the debugger's execution state.
|
// DebuggerCommand is a command which changes the debugger's execution state.
|
||||||
type DebuggerCommand struct {
|
type DebuggerCommand struct {
|
||||||
// Name is the command to run.
|
// Name is the command to run.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user