runtime: ignore _Gscan bit when checking status in CgocallDone
authorIan Lance Taylor <ian@gcc.gnu.org>
Mon, 12 Jun 2017 23:14:05 +0000 (23:14 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Mon, 12 Jun 2017 23:14:05 +0000 (23:14 +0000)
    Also always access the atomicstatus field atomically.

    The effect of not checking the _Gscan bit is that if the GC decides to
    scan the stack just as the goroutine is leaving the system call, the
    goroutine might fail to call exitsyscall.  Then then typically causes
    a runtime assertion failure later on.  If we do call exitsyscall as we
    should, it will stall (in casgstatus) until the _Gscan bit is cleared.

    No separate test.  I've observed causing sporadic failures running the
    misc/cgo tests, but we don't currently have a way to run those
    routinely for gccgo.  I should fix that.

    Reviewed-on: https://go-review.googlesource.com/45392

From-SVN: r249138

gcc/go/gofrontend/MERGE
libgo/go/runtime/cgo_gccgo.go
libgo/go/runtime/proc.go

index aebab77b1d3977ff75c2f5dd09a0b4b216742aba..d4a312908f0ef14633e04fe9b19f5fffc76008d1 100644 (file)
@@ -1,4 +1,4 @@
-61222d34c1b33a369bd86008a0541455dd17727e
+908fc7e46ebe36658ed86b65a3d165fccb2e8576
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index a55fb436bc563fd055f1345c457c972dbdf7a5cb..b0ad2f12a6356bf6959e5e210dfeb5656cdfe762 100644 (file)
@@ -54,7 +54,7 @@ func CgocallDone() {
 
        // If we are invoked because the C function called _cgo_panic,
        // then _cgo_panic will already have exited syscall mode.
-       if gp.atomicstatus == _Gsyscall {
+       if readgstatus(gp)&^_Gscan == _Gsyscall {
                exitsyscall(0)
        }
 
index 64735e2a653259f1f641939507989bb6c6b3e896..038f20e977ef4a8e51ae66ce8ecf7c9680917ddb 100644 (file)
@@ -1459,7 +1459,7 @@ func dropm() {
 
        // gccgo sets the stack to Gdead here, because the splitstack
        // context is not initialized.
-       mp.curg.atomicstatus = _Gdead
+       atomic.Store(&mp.curg.atomicstatus, _Gdead)
        mp.curg.gcstack = nil
        mp.curg.gcnextsp = nil