• Dan Scales's avatar
    runtime: ensure that Goexit cannot be aborted by a recursive panic/recover · 7dcd343e
    Dan Scales authored
    When we do a successful recover of a panic, we resume normal execution by
    returning from the frame that had the deferred call that did the recover (after
    executing any remaining deferred calls in that frame).
    
    However, suppose we have called runtime.Goexit and there is a panic during one of the
    deferred calls run by the Goexit. Further assume that there is a deferred call in
    the frame of the Goexit or a parent frame that does a recover. Then the recovery
    process will actually resume normal execution above the Goexit frame and hence
    abort the Goexit.  We will not terminate the thread as expected, but continue
    running in the frame above the Goexit.
    
    To fix this, we explicitly create a _panic object for a Goexit call. We then
    change the "abort" behavior for Goexits, but not panics. After a recovery, if the
    top-level panic is actually a Goexit that is marked to be aborted, then we return
    to the Goexit defer-processing loop, so that the Goexit is not actually aborted.
    
    Actual code changes are just panic.go, runtime2.go, and funcid.go. Adjusted the
    test related to the new Goexit behavior (TestRecoverBeforePanicAfterGoexit) and
    added several new tests of aborted panics (whose behavior has not changed).
    
    Fixes #29226
    
    Change-Id: Ib13cb0074f5acc2567a28db7ca6912cfc47eecb5
    Reviewed-on: https://go-review.googlesource.com/c/go/+/200081
    Run-TryBot: Dan Scales <danscales@google.com>
    Reviewed-by: default avatarKeith Randall <khr@golang.org>
    7dcd343e
issue8047b.go 575 Bytes