]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.7] runtime: improve diagnostics for "scan missed a g"
authorAustin Clements <austin@google.com>
Thu, 17 Nov 2016 15:48:40 +0000 (10:48 -0500)
committerBrad Fitzpatrick <bradfitz@golang.org>
Wed, 25 Jan 2017 17:16:44 +0000 (17:16 +0000)
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>
src/runtime/mgcmark.go

index aa7f7a7769303ff83a18b2c88e97a0707cec8e97..e5000ed086b44b307651a8536a3d73f9e6b067a8 100644 (file)
@@ -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.