]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: replace system goroutine whitelist with symbol test
authorAustin Clements <austin@google.com>
Fri, 1 Dec 2017 21:13:08 +0000 (16:13 -0500)
committerAustin Clements <austin@google.com>
Mon, 7 May 2018 21:38:40 +0000 (21:38 +0000)
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>
src/cmd/internal/objabi/funcid.go
src/cmd/link/internal/ld/pcln.go
src/cmd/trace/trace.go
src/runtime/symtab.go
src/runtime/traceback.go

index 55f1328ba8462a52e0c2f1104ffc060a1080c984..ff75d3d571702fab3c27c22219b9fd3eb285593b 100644 (file)
@@ -13,6 +13,7 @@ type FuncID uint32
 
 const (
        FuncID_normal FuncID = iota // not a special function
+       FuncID_runtime_main
        FuncID_goexit
        FuncID_jmpdefer
        FuncID_mcall
@@ -22,9 +23,6 @@ const (
        FuncID_asmcgocall
        FuncID_sigpanic
        FuncID_runfinq
-       FuncID_bgsweep
-       FuncID_forcegchelper
-       FuncID_timerproc
        FuncID_gcBgMarkWorker
        FuncID_systemstack_switch
        FuncID_systemstack
index 446f64bdbc6ec3b4fe5484724729ac18c694ee4d..1bd4d1d762b5088a4e54a2a88de286834e0ff525 100644 (file)
@@ -312,6 +312,8 @@ func (ctxt *Link) pclntab() {
                // funcID uint32
                funcID := objabi.FuncID_normal
                switch s.Name {
+               case "runtime.main":
+                       funcID = objabi.FuncID_runtime_main
                case "runtime.goexit":
                        funcID = objabi.FuncID_goexit
                case "runtime.jmpdefer":
@@ -330,12 +332,6 @@ func (ctxt *Link) pclntab() {
                        funcID = objabi.FuncID_sigpanic
                case "runtime.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":
                        funcID = objabi.FuncID_gcBgMarkWorker
                case "runtime.systemstack_switch":
index 7a61d5b412ad7174a3d731a3fd2fb04fc9011aa3..fcba0cbc3fb3d87b39daac637f754cbd055ca88f 100644 (file)
@@ -576,7 +576,7 @@ func generateTrace(params *traceParams, consumer traceConsumer) error {
 
                        fname := stk[0].Fn
                        info.name = fmt.Sprintf("G%v %s", newG, fname)
-                       info.isSystemG = strings.HasPrefix(fname, "runtime.") && fname != "runtime.main"
+                       info.isSystemG = isSystemGoroutine(fname)
 
                        ctx.gcount++
                        setGState(ev, newG, gDead, gRunnable)
@@ -1125,6 +1125,12 @@ func (ctx *traceContext) buildBranch(parent frameNode, stk []*trace.Frame) int {
        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.
 func firstTimestamp() int64 {
        res, _ := parseTrace()
index 8d54369d88a3bb566cdd62d19aab88837c545856..c829bfdec1129e5d346800edd8f085dffc600fbd 100644 (file)
@@ -358,6 +358,7 @@ type funcID uint32
 
 const (
        funcID_normal funcID = iota // not a special function
+       funcID_runtime_main
        funcID_goexit
        funcID_jmpdefer
        funcID_mcall
@@ -367,9 +368,6 @@ const (
        funcID_asmcgocall
        funcID_sigpanic
        funcID_runfinq
-       funcID_bgsweep
-       funcID_forcegchelper
-       funcID_timerproc
        funcID_gcBgMarkWorker
        funcID_systemstack_switch
        funcID_systemstack
index fd649cbbc691eb50d91b15c77cee62b941e5a5df..0fd7ef198729361862b9e9846e59734f7155cb24 100644 (file)
@@ -990,18 +990,25 @@ func topofstack(f funcInfo, g0 bool) bool {
                (g0 && f.funcID == funcID_asmcgocall)
 }
 
-// isSystemGoroutine reports whether the goroutine g must be omitted in
-// stack dumps and deadlock detector.
+// isSystemGoroutine reports whether the goroutine g must be omitted
+// 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 {
+       // Keep this in sync with cmd/trace/trace.go:isSystemGoroutine.
        f := findfunc(gp.startpc)
        if !f.valid() {
                return false
        }
-       return f.funcID == funcID_runfinq && !fingRunning ||
-               f.funcID == funcID_bgsweep ||
-               f.funcID == funcID_forcegchelper ||
-               f.funcID == funcID_timerproc ||
-               f.funcID == funcID_gcBgMarkWorker
+       if f.funcID == funcID_runtime_main {
+               return false
+       }
+       if f.funcID == funcID_runfinq {
+               // 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