const (
FuncID_normal FuncID = iota // not a special function
+ FuncID_runtime_main
FuncID_goexit
FuncID_jmpdefer
FuncID_mcall
FuncID_asmcgocall
FuncID_sigpanic
FuncID_runfinq
- FuncID_bgsweep
- FuncID_forcegchelper
- FuncID_timerproc
FuncID_gcBgMarkWorker
FuncID_systemstack_switch
FuncID_systemstack
// 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":
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":
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)
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()
const (
funcID_normal funcID = iota // not a special function
+ funcID_runtime_main
funcID_goexit
funcID_jmpdefer
funcID_mcall
funcID_asmcgocall
funcID_sigpanic
funcID_runfinq
- funcID_bgsweep
- funcID_forcegchelper
- funcID_timerproc
funcID_gcBgMarkWorker
funcID_systemstack_switch
funcID_systemstack
(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