proc,service,terminal: propagate g.startpc
Adds StartPC to proc.G, StartLoc to api.Goroutine and show the start location in the command line client when appropriate. Updates #1104
This commit is contained in:
parent
bdcbd8a846
commit
2309f728c1
@ -203,13 +203,14 @@ Called with more arguments it will execute a command on the specified goroutine.
|
|||||||
## goroutines
|
## goroutines
|
||||||
List program goroutines.
|
List program goroutines.
|
||||||
|
|
||||||
goroutines [-u (default: user location)|-r (runtime location)|-g (go statement location) ] [ -t (stack trace)]
|
goroutines [-u (default: user location)|-r (runtime location)|-g (go statement location)|-s (start location)] [ -t (stack trace)]
|
||||||
|
|
||||||
Print out info for every goroutine. The flag controls what information is shown along with each goroutine:
|
Print out info for every goroutine. The flag controls what information is shown along with each goroutine:
|
||||||
|
|
||||||
-u displays location of topmost stackframe in user code
|
-u displays location of topmost stackframe in user code
|
||||||
-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
|
||||||
-t displays stack trace of goroutine
|
-t displays stack trace of goroutine
|
||||||
|
|
||||||
If no flag is specified the default is -u.
|
If no flag is specified the default is -u.
|
||||||
|
|||||||
@ -143,6 +143,7 @@ type G struct {
|
|||||||
SP uint64 // SP of goroutine when it was parked.
|
SP uint64 // SP of goroutine when it was parked.
|
||||||
BP uint64 // BP of goroutine when it was parked (go >= 1.7).
|
BP uint64 // BP of goroutine when it was parked (go >= 1.7).
|
||||||
GoPC uint64 // PC of 'go' statement that created this goroutine.
|
GoPC uint64 // PC of 'go' statement that created this goroutine.
|
||||||
|
StartPC uint64 // PC of the first function run on this goroutine.
|
||||||
WaitReason string // Reason for goroutine being parked.
|
WaitReason string // Reason for goroutine being parked.
|
||||||
Status uint64
|
Status uint64
|
||||||
stkbarVar *Variable // stkbar field of g struct
|
stkbarVar *Variable // stkbar field of g struct
|
||||||
@ -422,6 +423,7 @@ func (gvar *Variable) parseG() (*G, error) {
|
|||||||
}
|
}
|
||||||
id, _ := constant.Int64Val(gvar.fieldVariable("goid").Value)
|
id, _ := constant.Int64Val(gvar.fieldVariable("goid").Value)
|
||||||
gopc, _ := constant.Int64Val(gvar.fieldVariable("gopc").Value)
|
gopc, _ := constant.Int64Val(gvar.fieldVariable("gopc").Value)
|
||||||
|
startpc, _ := constant.Int64Val(gvar.fieldVariable("startpc").Value)
|
||||||
waitReason := ""
|
waitReason := ""
|
||||||
if wrvar := gvar.fieldVariable("waitreason"); wrvar.Value != nil {
|
if wrvar := gvar.fieldVariable("waitreason"); wrvar.Value != nil {
|
||||||
switch wrvar.Kind {
|
switch wrvar.Kind {
|
||||||
@ -451,6 +453,7 @@ func (gvar *Variable) parseG() (*G, error) {
|
|||||||
g := &G{
|
g := &G{
|
||||||
ID: int(id),
|
ID: int(id),
|
||||||
GoPC: uint64(gopc),
|
GoPC: uint64(gopc),
|
||||||
|
StartPC: uint64(startpc),
|
||||||
PC: uint64(pc),
|
PC: uint64(pc),
|
||||||
SP: uint64(sp),
|
SP: uint64(sp),
|
||||||
BP: uint64(bp),
|
BP: uint64(bp),
|
||||||
@ -553,6 +556,12 @@ func (g *G) Go() Location {
|
|||||||
return Location{PC: g.GoPC, File: f, Line: l, Fn: fn}
|
return Location{PC: g.GoPC, File: f, Line: l, Fn: fn}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StartLoc returns the starting location of the goroutine.
|
||||||
|
func (g *G) StartLoc() Location {
|
||||||
|
f, l, fn := g.variable.bi.PCToLine(g.StartPC)
|
||||||
|
return Location{PC: g.StartPC, File: f, Line: l, Fn: fn}
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the list of saved return addresses used by stack barriers
|
// Returns the list of saved return addresses used by stack barriers
|
||||||
func (g *G) stkbar() ([]savedLR, error) {
|
func (g *G) stkbar() ([]savedLR, error) {
|
||||||
if g.stkbarVar == nil { // stack barriers were removed in Go 1.9
|
if g.stkbarVar == nil { // stack barriers were removed in Go 1.9
|
||||||
|
|||||||
@ -142,13 +142,14 @@ See also: "help on", "help cond" and "help clear"`},
|
|||||||
If called with the linespec argument it will delete all the breakpoints matching the linespec. If linespec is omitted all breakpoints are deleted.`},
|
If called with the linespec argument it will delete all the breakpoints matching the linespec. If linespec is omitted all breakpoints are deleted.`},
|
||||||
{aliases: []string{"goroutines"}, cmdFn: goroutines, helpMsg: `List program goroutines.
|
{aliases: []string{"goroutines"}, cmdFn: goroutines, helpMsg: `List program goroutines.
|
||||||
|
|
||||||
goroutines [-u (default: user location)|-r (runtime location)|-g (go statement location) ] [ -t (stack trace)]
|
goroutines [-u (default: user location)|-r (runtime location)|-g (go statement location)|-s (start location)] [ -t (stack trace)]
|
||||||
|
|
||||||
Print out info for every goroutine. The flag controls what information is shown along with each goroutine:
|
Print out info for every goroutine. The flag controls what information is shown along with each goroutine:
|
||||||
|
|
||||||
-u displays location of topmost stackframe in user code
|
-u displays location of topmost stackframe in user code
|
||||||
-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
|
||||||
-t displays stack trace of goroutine
|
-t displays stack trace of goroutine
|
||||||
|
|
||||||
If no flag is specified the default is -u.`},
|
If no flag is specified the default is -u.`},
|
||||||
@ -544,6 +545,8 @@ func goroutines(t *Term, ctx callContext, argstr string) error {
|
|||||||
fgl = fglRuntimeCurrent
|
fgl = fglRuntimeCurrent
|
||||||
case "-g":
|
case "-g":
|
||||||
fgl = fglGo
|
fgl = fglGo
|
||||||
|
case "-s":
|
||||||
|
fgl = fglStart
|
||||||
case "-t":
|
case "-t":
|
||||||
bPrintStack = true
|
bPrintStack = true
|
||||||
case "":
|
case "":
|
||||||
@ -706,6 +709,7 @@ const (
|
|||||||
fglRuntimeCurrent = formatGoroutineLoc(iota)
|
fglRuntimeCurrent = formatGoroutineLoc(iota)
|
||||||
fglUserCurrent
|
fglUserCurrent
|
||||||
fglGo
|
fglGo
|
||||||
|
fglStart
|
||||||
)
|
)
|
||||||
|
|
||||||
func formatLocation(loc api.Location) string {
|
func formatLocation(loc api.Location) string {
|
||||||
@ -732,6 +736,9 @@ func formatGoroutine(g *api.Goroutine, fgl formatGoroutineLoc) string {
|
|||||||
case fglGo:
|
case fglGo:
|
||||||
locname = "Go"
|
locname = "Go"
|
||||||
loc = g.GoStatementLoc
|
loc = g.GoStatementLoc
|
||||||
|
case fglStart:
|
||||||
|
locname = "Start"
|
||||||
|
loc = g.StartLoc
|
||||||
}
|
}
|
||||||
thread := ""
|
thread := ""
|
||||||
if g.ThreadID != 0 {
|
if g.ThreadID != 0 {
|
||||||
@ -741,11 +748,12 @@ func formatGoroutine(g *api.Goroutine, fgl formatGoroutineLoc) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func writeGoroutineLong(w io.Writer, g *api.Goroutine, prefix string) {
|
func writeGoroutineLong(w io.Writer, g *api.Goroutine, prefix string) {
|
||||||
fmt.Fprintf(w, "%sGoroutine %d:\n%s\tRuntime: %s\n%s\tUser: %s\n%s\tGo: %s\n",
|
fmt.Fprintf(w, "%sGoroutine %d:\n%s\tRuntime: %s\n%s\tUser: %s\n%s\tGo: %s\n%s\tStart: %s\n",
|
||||||
prefix, g.ID,
|
prefix, g.ID,
|
||||||
prefix, formatLocation(g.CurrentLoc),
|
prefix, formatLocation(g.CurrentLoc),
|
||||||
prefix, formatLocation(g.UserCurrentLoc),
|
prefix, formatLocation(g.UserCurrentLoc),
|
||||||
prefix, formatLocation(g.GoStatementLoc))
|
prefix, formatLocation(g.GoStatementLoc),
|
||||||
|
prefix, formatLocation(g.StartLoc))
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseArgs(args string) ([]string, error) {
|
func parseArgs(args string) ([]string, error) {
|
||||||
|
|||||||
@ -235,6 +235,7 @@ func ConvertGoroutine(g *proc.G) *Goroutine {
|
|||||||
CurrentLoc: ConvertLocation(g.CurrentLoc),
|
CurrentLoc: ConvertLocation(g.CurrentLoc),
|
||||||
UserCurrentLoc: ConvertLocation(g.UserCurrent()),
|
UserCurrentLoc: ConvertLocation(g.UserCurrent()),
|
||||||
GoStatementLoc: ConvertLocation(g.Go()),
|
GoStatementLoc: ConvertLocation(g.Go()),
|
||||||
|
StartLoc: ConvertLocation(g.StartLoc()),
|
||||||
ThreadID: tid,
|
ThreadID: tid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -256,6 +256,8 @@ type Goroutine struct {
|
|||||||
UserCurrentLoc Location `json:"userCurrentLoc"`
|
UserCurrentLoc Location `json:"userCurrentLoc"`
|
||||||
// Location of the go instruction that started this goroutine
|
// Location of the go instruction that started this goroutine
|
||||||
GoStatementLoc Location `json:"goStatementLoc"`
|
GoStatementLoc Location `json:"goStatementLoc"`
|
||||||
|
// Location of the starting function
|
||||||
|
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"`
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user