diff options
author | Ian Lance Taylor <iant@golang.org> | 2020-10-27 16:09:40 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2020-11-20 20:38:12 +0000 |
commit | efd204ccf78e16ee6792079ba70456ed425cb9c3 (patch) | |
tree | 1f37f9e107e7218377e72064d8e6fc2d3257603a /src/runtime/proc.go | |
parent | 730d5f42f919f948ff2841581ecec6fe4b465aee (diff) | |
download | go-efd204ccf78e16ee6792079ba70456ed425cb9c3.tar.gz go-efd204ccf78e16ee6792079ba70456ed425cb9c3.zip |
[release-branch.go1.15] runtime: block signals in needm before allocating M
Otherwise, if a signal occurs just after we allocated the M,
we can deadlock if the signal handler needs to allocate an M
itself.
For #42207
Fixes #42636
Change-Id: I76f44547f419e8b1c14cbf49bf602c6e645d8c14
Reviewed-on: https://go-review.googlesource.com/c/go/+/265759
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
(cherry picked from commit 368c40116434532dc0b53b72fa04788ca6742898)
Reviewed-on: https://go-review.googlesource.com/c/go/+/271847
Diffstat (limited to 'src/runtime/proc.go')
-rw-r--r-- | src/runtime/proc.go | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/src/runtime/proc.go b/src/runtime/proc.go index 2f1272d310..7fa19d867b 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -569,7 +569,7 @@ func schedinit() { typelinksinit() // uses maps, activeModules itabsinit() // uses activeModules - msigsave(_g_.m) + sigsave(&_g_.m.sigmask) initSigmask = _g_.m.sigmask goargs() @@ -1536,6 +1536,18 @@ func needm(x byte) { exit(1) } + // Save and block signals before getting an M. + // The signal handler may call needm itself, + // and we must avoid a deadlock. Also, once g is installed, + // any incoming signals will try to execute, + // but we won't have the sigaltstack settings and other data + // set up appropriately until the end of minit, which will + // unblock the signals. This is the same dance as when + // starting a new m to run Go code via newosproc. + var sigmask sigset + sigsave(&sigmask) + sigblock() + // Lock extra list, take head, unlock popped list. // nilokay=false is safe here because of the invariant above, // that the extra list always contains or will soon contain @@ -1553,14 +1565,8 @@ func needm(x byte) { extraMCount-- unlockextra(mp.schedlink.ptr()) - // Save and block signals before installing g. - // Once g is installed, any incoming signals will try to execute, - // but we won't have the sigaltstack settings and other data - // set up appropriately until the end of minit, which will - // unblock the signals. This is the same dance as when - // starting a new m to run Go code via newosproc. - msigsave(mp) - sigblock() + // Store the original signal mask for use by minit. + mp.sigmask = sigmask // Install g (= m->g0) and set the stack bounds // to match the current stack. We don't actually know @@ -3417,7 +3423,7 @@ func beforefork() { // a signal handler before exec if a signal is sent to the process // group. See issue #18600. gp.m.locks++ - msigsave(gp.m) + sigsave(&gp.m.sigmask) sigblock() // This function is called before fork in syscall package. |