mirror of https://github.com/golang/go.git
runtime: capture pause stack for late gcWork put debugging
This captures the stack trace where mark completion observed that each P had no work, and then dumps this if that P later discovers more work. Hopefully this will help bound where the work was created. For #27993. Change-Id: I4f29202880d22c433482dc1463fb50ab693b6de6 Reviewed-on: https://go-review.googlesource.com/c/154599 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
parent
db1e8a9e1f
commit
ccbca561ef
|
|
@ -1453,6 +1453,11 @@ top:
|
||||||
// there's a paused gcWork, then
|
// there's a paused gcWork, then
|
||||||
// that's a bug.
|
// that's a bug.
|
||||||
_p_.gcw.pauseGen = gcWorkPauseGen
|
_p_.gcw.pauseGen = gcWorkPauseGen
|
||||||
|
// Capture the G's stack.
|
||||||
|
for i := range _p_.gcw.pauseStack {
|
||||||
|
_p_.gcw.pauseStack[i] = 0
|
||||||
|
}
|
||||||
|
callers(1, _p_.gcw.pauseStack[:])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
casgstatus(gp, _Gwaiting, _Grunning)
|
casgstatus(gp, _Gwaiting, _Grunning)
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,10 @@ type gcWork struct {
|
||||||
// pauseGen causes put operations to spin while pauseGen ==
|
// pauseGen causes put operations to spin while pauseGen ==
|
||||||
// gcWorkPauseGen if debugCachedWork is true.
|
// gcWorkPauseGen if debugCachedWork is true.
|
||||||
pauseGen uint32
|
pauseGen uint32
|
||||||
|
|
||||||
|
// pauseStack is the stack at which this P was paused if
|
||||||
|
// debugCachedWork is true.
|
||||||
|
pauseStack [16]uintptr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Most of the methods of gcWork are go:nowritebarrierrec because the
|
// Most of the methods of gcWork are go:nowritebarrierrec because the
|
||||||
|
|
@ -128,6 +132,23 @@ func (w *gcWork) checkPut(ptr uintptr, ptrs []uintptr) {
|
||||||
for _, ptr := range ptrs {
|
for _, ptr := range ptrs {
|
||||||
gcDumpObject("ptrs", ptr, ^uintptr(0))
|
gcDumpObject("ptrs", ptr, ^uintptr(0))
|
||||||
}
|
}
|
||||||
|
println("runtime: paused at")
|
||||||
|
for _, pc := range w.pauseStack {
|
||||||
|
if pc == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
f := findfunc(pc)
|
||||||
|
if f.valid() {
|
||||||
|
// Obviously this doesn't
|
||||||
|
// relate to ancestor
|
||||||
|
// tracebacks, but this
|
||||||
|
// function prints what we
|
||||||
|
// want.
|
||||||
|
printAncestorTracebackFuncInfo(f, pc)
|
||||||
|
} else {
|
||||||
|
println("\tunknown PC ", hex(pc), "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
throw("throwOnGCWork")
|
throw("throwOnGCWork")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue