aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2016-12-20 15:37:56 -0500
committerAustin Clements <austin@google.com>2016-12-21 16:39:01 +0000
commitf24384f686745f95086e7f400e884a218f4456d3 (patch)
treeb031b8d0de5e25f2828763f76c945a00ff26dca0
parentc44da14440e5a2e412f9b1d3f5f2f562591d8e49 (diff)
downloadgo-f24384f686745f95086e7f400e884a218f4456d3.tar.gz
go-f24384f686745f95086e7f400e884a218f4456d3.zip
runtime: avoid CreateThread panic when exiting process
On Windows, CreateThread occasionally fails with ERROR_ACCESS_DENIED. We're not sure why this is, but the Wine source code suggests that this can happen when there's a concurrent CreateThread and ExitProcess in the same process. Fix this by setting a flag right before calling ExitProcess and halting if CreateThread fails and this flag is set. Updates #18253 (might fix it, but we're not sure this is the issue and can't reproduce it on demand). Change-Id: I1945b989e73a16cf28a35bf2613ffab07577ed4e Reviewed-on: https://go-review.googlesource.com/34616 TryBot-Result: Gobot Gobot <gobot@golang.org> Run-TryBot: Austin Clements <austin@google.com> Reviewed-by: Alex Brainman <alex.brainman@gmail.com> Reviewed-by: Ian Lance Taylor <iant@golang.org>
-rw-r--r--src/runtime/os_windows.go12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
index 10cab90d47..75b8acdceb 100644
--- a/src/runtime/os_windows.go
+++ b/src/runtime/os_windows.go
@@ -332,8 +332,12 @@ func goenvs() {
stdcall1(_FreeEnvironmentStringsW, uintptr(strings))
}
+// exiting is set to non-zero when the process is exiting.
+var exiting uint32
+
//go:nosplit
func exit(code int32) {
+ atomic.Store(&exiting, 1)
stdcall1(_ExitProcess, uintptr(code))
}
@@ -519,6 +523,14 @@ func newosproc(mp *m, stk unsafe.Pointer) {
_STACK_SIZE_PARAM_IS_A_RESERVATION, 0)
if thandle == 0 {
+ if atomic.Load(&exiting) != 0 {
+ // CreateThread may fail if called
+ // concurrently with ExitProcess. If this
+ // happens, just freeze this thread and let
+ // the process exit. See issue #18253.
+ lock(&deadlock)
+ lock(&deadlock)
+ }
print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", getlasterror(), ")\n")
throw("runtime.newosproc")
}