From: Austin Clements Date: Tue, 20 Dec 2016 20:37:56 +0000 (-0500) Subject: runtime: avoid CreateThread panic when exiting process X-Git-Tag: go1.8rc1~61 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=f24384f686745f95086e7f400e884a218f4456d3;p=gostls13.git 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 Run-TryBot: Austin Clements Reviewed-by: Alex Brainman Reviewed-by: Ian Lance Taylor --- 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") }