terminal: add ability to print goroutine labels (#1879)
This commit is contained in:
parent
ade20a4d4d
commit
186786235f
@ -274,7 +274,8 @@ Print out info for every goroutine. The flag controls what information is shown
|
|||||||
-r displays location of topmost stackframe (including frames inside private runtime functions)
|
-r displays location of topmost stackframe (including frames inside private runtime functions)
|
||||||
-g displays location of go instruction that created the goroutine
|
-g displays location of go instruction that created the goroutine
|
||||||
-s displays location of the start function
|
-s displays location of the start function
|
||||||
-t displays stack trace of goroutine
|
-t displays goroutine's stacktrace
|
||||||
|
-l displays goroutine's labels
|
||||||
|
|
||||||
If no flag is specified the default is -u.
|
If no flag is specified the default is -u.
|
||||||
|
|
||||||
|
|||||||
@ -189,7 +189,8 @@ Print out info for every goroutine. The flag controls what information is shown
|
|||||||
-r displays location of topmost stackframe (including frames inside private runtime functions)
|
-r displays location of topmost stackframe (including frames inside private runtime functions)
|
||||||
-g displays location of go instruction that created the goroutine
|
-g displays location of go instruction that created the goroutine
|
||||||
-s displays location of the start function
|
-s displays location of the start function
|
||||||
-t displays stack trace of goroutine
|
-t displays goroutine's stacktrace
|
||||||
|
-l displays goroutine's labels
|
||||||
|
|
||||||
If no flag is specified the default is -u.`},
|
If no flag is specified the default is -u.`},
|
||||||
{aliases: []string{"goroutine", "gr"}, allowedPrefixes: onPrefix, cmdFn: c.goroutine, helpMsg: `Shows or changes current goroutine
|
{aliases: []string{"goroutine", "gr"}, allowedPrefixes: onPrefix, cmdFn: c.goroutine, helpMsg: `Shows or changes current goroutine
|
||||||
@ -612,14 +613,24 @@ func (a byGoroutineID) Less(i, j int) bool { return a[i].ID < a[j].ID }
|
|||||||
// The number of goroutines we're going to request on each RPC call
|
// The number of goroutines we're going to request on each RPC call
|
||||||
const goroutineBatchSize = 10000
|
const goroutineBatchSize = 10000
|
||||||
|
|
||||||
func printGoroutines(t *Term, gs []*api.Goroutine, fgl formatGoroutineLoc, bPrintStack bool, state *api.DebuggerState) error {
|
type printGoroutinesFlags uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
printGoroutinesStack printGoroutinesFlags = 1 << iota
|
||||||
|
printGoroutinesLabels
|
||||||
|
)
|
||||||
|
|
||||||
|
func printGoroutines(t *Term, gs []*api.Goroutine, fgl formatGoroutineLoc, flags printGoroutinesFlags, state *api.DebuggerState) error {
|
||||||
for _, g := range gs {
|
for _, g := range gs {
|
||||||
prefix := " "
|
prefix := " "
|
||||||
if state.SelectedGoroutine != nil && g.ID == state.SelectedGoroutine.ID {
|
if state.SelectedGoroutine != nil && g.ID == state.SelectedGoroutine.ID {
|
||||||
prefix = "* "
|
prefix = "* "
|
||||||
}
|
}
|
||||||
fmt.Printf("%sGoroutine %s\n", prefix, formatGoroutine(g, fgl))
|
fmt.Printf("%sGoroutine %s\n", prefix, formatGoroutine(g, fgl))
|
||||||
if bPrintStack {
|
if flags&printGoroutinesLabels != 0 {
|
||||||
|
writeGoroutineLabels(os.Stdout, g, "\t")
|
||||||
|
}
|
||||||
|
if flags&printGoroutinesStack != 0 {
|
||||||
stack, err := t.client.Stacktrace(g.ID, 10, 0, nil)
|
stack, err := t.client.Stacktrace(g.ID, 10, 0, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -633,7 +644,7 @@ func printGoroutines(t *Term, gs []*api.Goroutine, fgl formatGoroutineLoc, bPrin
|
|||||||
func goroutines(t *Term, ctx callContext, argstr string) error {
|
func goroutines(t *Term, ctx callContext, argstr string) error {
|
||||||
args := strings.Split(argstr, " ")
|
args := strings.Split(argstr, " ")
|
||||||
var fgl = fglUserCurrent
|
var fgl = fglUserCurrent
|
||||||
bPrintStack := false
|
var flags printGoroutinesFlags
|
||||||
|
|
||||||
switch len(args) {
|
switch len(args) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -650,7 +661,9 @@ func goroutines(t *Term, ctx callContext, argstr string) error {
|
|||||||
case "-s":
|
case "-s":
|
||||||
fgl = fglStart
|
fgl = fglStart
|
||||||
case "-t":
|
case "-t":
|
||||||
bPrintStack = true
|
flags |= printGoroutinesStack
|
||||||
|
case "-l":
|
||||||
|
flags |= printGoroutinesLabels
|
||||||
case "":
|
case "":
|
||||||
// nothing to do
|
// nothing to do
|
||||||
default:
|
default:
|
||||||
@ -675,7 +688,7 @@ func goroutines(t *Term, ctx callContext, argstr string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sort.Sort(byGoroutineID(gs))
|
sort.Sort(byGoroutineID(gs))
|
||||||
err = printGoroutines(t, gs, fgl, bPrintStack, state)
|
err = printGoroutines(t, gs, fgl, flags, state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -877,6 +890,36 @@ func writeGoroutineLong(w io.Writer, g *api.Goroutine, prefix string) {
|
|||||||
prefix, formatLocation(g.UserCurrentLoc),
|
prefix, formatLocation(g.UserCurrentLoc),
|
||||||
prefix, formatLocation(g.GoStatementLoc),
|
prefix, formatLocation(g.GoStatementLoc),
|
||||||
prefix, formatLocation(g.StartLoc))
|
prefix, formatLocation(g.StartLoc))
|
||||||
|
writeGoroutineLabels(w, g, prefix+"\t")
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeGoroutineLabels(w io.Writer, g *api.Goroutine, prefix string) {
|
||||||
|
const maxNumberOfGoroutineLabels = 5
|
||||||
|
|
||||||
|
if len(g.Labels) <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
keys := make([]string, 0, len(g.Labels))
|
||||||
|
for k := range g.Labels {
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
sort.Strings(keys)
|
||||||
|
more := false
|
||||||
|
if len(keys) > maxNumberOfGoroutineLabels {
|
||||||
|
more = true
|
||||||
|
keys = keys[:maxNumberOfGoroutineLabels]
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "%sLabels: ", prefix)
|
||||||
|
for i, k := range keys {
|
||||||
|
fmt.Fprintf(w, "%q:%q", k, g.Labels[k])
|
||||||
|
if i != len(keys)-1 {
|
||||||
|
fmt.Fprintf(w, ", ")
|
||||||
|
} else if more {
|
||||||
|
fmt.Fprintf(w, "... (%d more)", len(g.Labels)-maxNumberOfGoroutineLabels)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func restart(t *Term, ctx callContext, args string) error {
|
func restart(t *Term, ctx callContext, args string) error {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user