Commit 44286b17 authored by Austin Clements's avatar Austin Clements

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: default avatarKeith Randall <khr@golang.org>
parent a8a05081
...@@ -13,6 +13,7 @@ type FuncID uint32 ...@@ -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 ( ...@@ -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() { ...@@ -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() { ...@@ -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 { ...@@ -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 { ...@@ -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 ...@@ -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 ( ...@@ -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 { ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment