aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2018-12-17 14:39:05 -0500
committerAustin Clements <austin@google.com>2018-12-17 21:24:19 +0000
commitccbca561ef1fc7990ca697102f0e9d3b2150d8f5 (patch)
treeb07534530e3b77cb3b687db85e914383e024f1bc
parentdb1e8a9e1f1b019dd7928ea239d5b0e4af66d9a6 (diff)
downloadgo-ccbca561ef1fc7990ca697102f0e9d3b2150d8f5.tar.gz
go-ccbca561ef1fc7990ca697102f0e9d3b2150d8f5.zip
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>
-rw-r--r--src/runtime/mgc.go5
-rw-r--r--src/runtime/mgcwork.go21
2 files changed, 26 insertions, 0 deletions
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index 622750ed2e..36d48d2561 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -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)
diff --git a/src/runtime/mgcwork.go b/src/runtime/mgcwork.go
index cdc94b8ffb..0ed0713442 100644
--- a/src/runtime/mgcwork.go
+++ b/src/runtime/mgcwork.go
@@ -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")
}
}