• Austin Clements's avatar
    runtime: call goexit1 instead of goexit · ad731887
    Austin Clements authored
    Currently, runtime.Goexit() calls goexit()—the goroutine exit stub—to
    terminate the goroutine. This *mostly* works, but can cause a
    "leftover stack barriers" panic if the following happens:
    
    1. Goroutine A has a reasonably large stack.
    
    2. The garbage collector scan phase runs and installs stack barriers
       in A's stack. The top-most stack barrier happens to fall at address X.
    
    3. Goroutine A unwinds the stack far enough to be a candidate for
       stack shrinking, but not past X.
    
    4. Goroutine A calls runtime.Goexit(), which calls goexit(), which
       calls goexit1().
    
    5. The garbage collector enters mark termination.
    
    6. Goroutine A is preempted right at the prologue of goexit1() and
       performs a stack shrink, which calls gentraceback.
    
    gentraceback stops as soon as it sees goexit on the stack, which is
    only two frames up at this point, even though there may really be many
    frames above it. More to the point, the stack barrier at X is above
    the goexit frame, so gentraceback never sees that stack barrier. At
    the end of gentraceback, it checks that it saw all of the stack
    barriers and panics because it didn't see the one at X.
    
    The fix is simple: call goexit1, which actually implements the process
    of exiting a goroutine, rather than goexit, the exit stub.
    
    To make sure this doesn't happen again in the future, we also add an
    argument to the stub prototype of goexit so you really, really have to
    want to call it in order to call it. We were able to reliably
    reproduce the above sequence with a fair amount of awful code inserted
    at the right places in the runtime, but chose to change the goexit
    prototype to ensure this wouldn't happen again rather than pollute the
    runtime with ugly testing code.
    
    Change-Id: Ifb6fb53087e09a252baddadc36eebf954468f2a8
    Reviewed-on: https://go-review.googlesource.com/13323Reviewed-by: 's avatarRuss Cox <rsc@golang.org>
    ad731887
stubs.go 11.5 KB