Commit ccbca561 authored by Austin Clements's avatar Austin Clements

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: 's avatarMichael Knyszek <mknyszek@google.com>
parent db1e8a9e
......@@ -1453,6 +1453,11 @@ top:
// there's a paused gcWork, then
// that's a bug.
_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)
......
......@@ -97,6 +97,10 @@ type gcWork struct {
// pauseGen causes put operations to spin while pauseGen ==
// gcWorkPauseGen if debugCachedWork is true.
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
......@@ -128,6 +132,23 @@ func (w *gcWork) checkPut(ptr uintptr, ptrs []uintptr) {
for _, ptr := range ptrs {
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")
}
}
......
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