• Austin Clements's avatar
    runtime: protect against external code calling ExitProcess · 957259b7
    Austin Clements authored
    On Windows, we implement asynchronous preemption using SuspendThread
    to suspend other threads in our process. However, SuspendThread is
    itself actually asynchronous (it enqueues a kernel "asynchronous
    procedure call" and returns). Unfortunately, Windows' ExitProcess API
    kills all threads except the calling one and then runs APCs. As a
    result, if SuspendThread and ExitProcess are called simultaneously,
    the exiting thread can be suspended and the suspending thread can be
    exited, leaving behind a ghost process consisting of a single thread
    that's suspended.
    
    We've already protected against the runtime's own calls to
    ExitProcess, but if Go code calls external code, there's nothing
    stopping that code from calling ExitProcess. For example, in #35775,
    our own call to racefini leads to C code calling ExitProcess and
    occasionally causing a deadlock.
    
    This CL fixes this by introducing synchronization between calling
    external code on Windows and preemption. It adds an atomic field to
    the M that participates in a simple CAS-based synchronization protocol
    to prevent suspending a thread running external code. We use this to
    protect cgocall (which is used for both cgo calls and system calls on
    Windows) and racefini.
    
    Tested by running the flag package's TestParse test compiled in race
    mode in a loop. Before this change, this would reliably deadlock after
    a few minutes.
    
    Fixes #35775.
    Updates #10958, #24543.
    
    Change-Id: I50d847abcdc2688b4f71eee6a75eca0f2fee892c
    Reviewed-on: https://go-review.googlesource.com/c/go/+/213837
    Run-TryBot: Austin Clements <austin@google.com>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
    Reviewed-by: default avatarDavid Chase <drchase@google.com>
    957259b7
cgocall.go 21.4 KB