From ccbca561ef1fc7990ca697102f0e9d3b2150d8f5 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Mon, 17 Dec 2018 14:39:05 -0500 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Michael Knyszek --- src/runtime/mgc.go | 5 +++++ src/runtime/mgcwork.go | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+) 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") } } -- 2.50.0