aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2016-11-17 10:48:40 -0500
committerBrad Fitzpatrick <bradfitz@golang.org>2017-01-25 17:16:44 +0000
commit70e980631c52e9705cd92cbc6904ed24f339e2d2 (patch)
treea2c76e9ebabb4892a9ac2a15452f1a9703c5f065
parent230a376b5a67f0e9341e1fa47e670ff762213c83 (diff)
downloadgo-70e980631c52e9705cd92cbc6904ed24f339e2d2.tar.gz
go-70e980631c52e9705cd92cbc6904ed24f339e2d2.zip
[release-branch.go1.7] runtime: improve diagnostics for "scan missed a g"
Updates #18700 (backport) Currently there are no diagnostics for mark root check during marking. Fix this by printing out the same diagnostics we print during mark termination. Also, drop the allglock before throwing. Holding that across a throw causes a self-deadlock with tracebackothers. For #16083. Change-Id: Ib605f3ae0c17e70704b31d8378274cfaa2307dc2 Reviewed-on: https://go-review.googlesource.com/35677 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-rw-r--r--src/runtime/mgcmark.go22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go
index aa7f7a7769..e5000ed086 100644
--- a/src/runtime/mgcmark.go
+++ b/src/runtime/mgcmark.go
@@ -106,26 +106,32 @@ func gcMarkRootCheck() {
lock(&allglock)
// Check that stacks have been scanned.
+ var gp *g
if gcphase == _GCmarktermination {
for i := 0; i < len(allgs); i++ {
- gp := allgs[i]
+ gp = allgs[i]
if !(gp.gcscandone && gp.gcscanvalid) && readgstatus(gp) != _Gdead {
- println("gp", gp, "goid", gp.goid,
- "status", readgstatus(gp),
- "gcscandone", gp.gcscandone,
- "gcscanvalid", gp.gcscanvalid)
- throw("scan missed a g")
+ goto fail
}
}
} else {
for i := 0; i < work.nStackRoots; i++ {
- gp := allgs[i]
+ gp = allgs[i]
if !gp.gcscandone {
- throw("scan missed a g")
+ goto fail
}
}
}
unlock(&allglock)
+ return
+
+fail:
+ println("gp", gp, "goid", gp.goid,
+ "status", readgstatus(gp),
+ "gcscandone", gp.gcscandone,
+ "gcscanvalid", gp.gcscanvalid)
+ unlock(&allglock) // Avoid self-deadlock with traceback.
+ throw("scan missed a g")
}
// ptrmask for an allocation containing a single pointer.