mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: replace system goroutine whitelist with symbol test
Currently isSystemGoroutine has a hard-coded list of known entry points into system goroutines. This list is annoying to maintain. For example, it's missing the ensureSigM goroutine. Replace it with a check that simply looks for any goroutine with runtime function as its entry point, with a few exceptions. This also matches the definition recently added to the trace viewer (CL 81315). Change-Id: Iaed723d4a6e8c2ffb7c0c48fbac1688b00b30f01 Reviewed-on: https://go-review.googlesource.com/81655 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
a8a050819b
commit
44286b17c5
5 changed files with 25 additions and 20 deletions
|
|
@ -13,6 +13,7 @@ type FuncID uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
FuncID_normal FuncID = iota // not a special function
|
FuncID_normal FuncID = iota // not a special function
|
||||||
|
FuncID_runtime_main
|
||||||
FuncID_goexit
|
FuncID_goexit
|
||||||
FuncID_jmpdefer
|
FuncID_jmpdefer
|
||||||
FuncID_mcall
|
FuncID_mcall
|
||||||
|
|
@ -22,9 +23,6 @@ const (
|
||||||
FuncID_asmcgocall
|
FuncID_asmcgocall
|
||||||
FuncID_sigpanic
|
FuncID_sigpanic
|
||||||
FuncID_runfinq
|
FuncID_runfinq
|
||||||
FuncID_bgsweep
|
|
||||||
FuncID_forcegchelper
|
|
||||||
FuncID_timerproc
|
|
||||||
FuncID_gcBgMarkWorker
|
FuncID_gcBgMarkWorker
|
||||||
FuncID_systemstack_switch
|
FuncID_systemstack_switch
|
||||||
FuncID_systemstack
|
FuncID_systemstack
|
||||||
|
|
|
||||||
|
|
@ -312,6 +312,8 @@ func (ctxt *Link) pclntab() {
|
||||||
// funcID uint32
|
// funcID uint32
|
||||||
funcID := objabi.FuncID_normal
|
funcID := objabi.FuncID_normal
|
||||||
switch s.Name {
|
switch s.Name {
|
||||||
|
case "runtime.main":
|
||||||
|
funcID = objabi.FuncID_runtime_main
|
||||||
case "runtime.goexit":
|
case "runtime.goexit":
|
||||||
funcID = objabi.FuncID_goexit
|
funcID = objabi.FuncID_goexit
|
||||||
case "runtime.jmpdefer":
|
case "runtime.jmpdefer":
|
||||||
|
|
@ -330,12 +332,6 @@ func (ctxt *Link) pclntab() {
|
||||||
funcID = objabi.FuncID_sigpanic
|
funcID = objabi.FuncID_sigpanic
|
||||||
case "runtime.runfinq":
|
case "runtime.runfinq":
|
||||||
funcID = objabi.FuncID_runfinq
|
funcID = objabi.FuncID_runfinq
|
||||||
case "runtime.bgsweep":
|
|
||||||
funcID = objabi.FuncID_bgsweep
|
|
||||||
case "runtime.forcegchelper":
|
|
||||||
funcID = objabi.FuncID_forcegchelper
|
|
||||||
case "runtime.timerproc":
|
|
||||||
funcID = objabi.FuncID_timerproc
|
|
||||||
case "runtime.gcBgMarkWorker":
|
case "runtime.gcBgMarkWorker":
|
||||||
funcID = objabi.FuncID_gcBgMarkWorker
|
funcID = objabi.FuncID_gcBgMarkWorker
|
||||||
case "runtime.systemstack_switch":
|
case "runtime.systemstack_switch":
|
||||||
|
|
|
||||||
|
|
@ -576,7 +576,7 @@ func generateTrace(params *traceParams, consumer traceConsumer) error {
|
||||||
|
|
||||||
fname := stk[0].Fn
|
fname := stk[0].Fn
|
||||||
info.name = fmt.Sprintf("G%v %s", newG, fname)
|
info.name = fmt.Sprintf("G%v %s", newG, fname)
|
||||||
info.isSystemG = strings.HasPrefix(fname, "runtime.") && fname != "runtime.main"
|
info.isSystemG = isSystemGoroutine(fname)
|
||||||
|
|
||||||
ctx.gcount++
|
ctx.gcount++
|
||||||
setGState(ev, newG, gDead, gRunnable)
|
setGState(ev, newG, gDead, gRunnable)
|
||||||
|
|
@ -1125,6 +1125,12 @@ func (ctx *traceContext) buildBranch(parent frameNode, stk []*trace.Frame) int {
|
||||||
return ctx.buildBranch(node, stk)
|
return ctx.buildBranch(node, stk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isSystemGoroutine(entryFn string) bool {
|
||||||
|
// This mimics runtime.isSystemGoroutine as closely as
|
||||||
|
// possible.
|
||||||
|
return entryFn != "runtime.main" && strings.HasPrefix(entryFn, "runtime.")
|
||||||
|
}
|
||||||
|
|
||||||
// firstTimestamp returns the timestamp of the first event record.
|
// firstTimestamp returns the timestamp of the first event record.
|
||||||
func firstTimestamp() int64 {
|
func firstTimestamp() int64 {
|
||||||
res, _ := parseTrace()
|
res, _ := parseTrace()
|
||||||
|
|
|
||||||
|
|
@ -358,6 +358,7 @@ type funcID uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
funcID_normal funcID = iota // not a special function
|
funcID_normal funcID = iota // not a special function
|
||||||
|
funcID_runtime_main
|
||||||
funcID_goexit
|
funcID_goexit
|
||||||
funcID_jmpdefer
|
funcID_jmpdefer
|
||||||
funcID_mcall
|
funcID_mcall
|
||||||
|
|
@ -367,9 +368,6 @@ const (
|
||||||
funcID_asmcgocall
|
funcID_asmcgocall
|
||||||
funcID_sigpanic
|
funcID_sigpanic
|
||||||
funcID_runfinq
|
funcID_runfinq
|
||||||
funcID_bgsweep
|
|
||||||
funcID_forcegchelper
|
|
||||||
funcID_timerproc
|
|
||||||
funcID_gcBgMarkWorker
|
funcID_gcBgMarkWorker
|
||||||
funcID_systemstack_switch
|
funcID_systemstack_switch
|
||||||
funcID_systemstack
|
funcID_systemstack
|
||||||
|
|
|
||||||
|
|
@ -990,18 +990,25 @@ func topofstack(f funcInfo, g0 bool) bool {
|
||||||
(g0 && f.funcID == funcID_asmcgocall)
|
(g0 && f.funcID == funcID_asmcgocall)
|
||||||
}
|
}
|
||||||
|
|
||||||
// isSystemGoroutine reports whether the goroutine g must be omitted in
|
// isSystemGoroutine reports whether the goroutine g must be omitted
|
||||||
// stack dumps and deadlock detector.
|
// in stack dumps and deadlock detector. This is any goroutine that
|
||||||
|
// starts at a runtime.* entry point, except for runtime.main and
|
||||||
|
// sometimes runtime.runfinq.
|
||||||
func isSystemGoroutine(gp *g) bool {
|
func isSystemGoroutine(gp *g) bool {
|
||||||
|
// Keep this in sync with cmd/trace/trace.go:isSystemGoroutine.
|
||||||
f := findfunc(gp.startpc)
|
f := findfunc(gp.startpc)
|
||||||
if !f.valid() {
|
if !f.valid() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return f.funcID == funcID_runfinq && !fingRunning ||
|
if f.funcID == funcID_runtime_main {
|
||||||
f.funcID == funcID_bgsweep ||
|
return false
|
||||||
f.funcID == funcID_forcegchelper ||
|
}
|
||||||
f.funcID == funcID_timerproc ||
|
if f.funcID == funcID_runfinq {
|
||||||
f.funcID == funcID_gcBgMarkWorker
|
// We include the finalizer goroutine if it's calling
|
||||||
|
// back into user code.
|
||||||
|
return !fingRunning
|
||||||
|
}
|
||||||
|
return hasprefix(funcname(f), "runtime.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCgoTraceback records three C functions to use to gather
|
// SetCgoTraceback records three C functions to use to gather
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue