From 9d8f56d6a636553cca90983cf565615697f2e740 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Wed, 13 Nov 2024 20:24:16 +0100 Subject: [PATCH] msys2-runtime: Update See https://github.com/msys2/msys2-runtime/pull/234 --- ...ad-suspend-thread-before-terminating.patch | 74 +++++++++++++++++++ msys2-runtime/PKGBUILD | 11 ++- 2 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 msys2-runtime/0042-cygthread-suspend-thread-before-terminating.patch diff --git a/msys2-runtime/0042-cygthread-suspend-thread-before-terminating.patch b/msys2-runtime/0042-cygthread-suspend-thread-before-terminating.patch new file mode 100644 index 00000000000..c659cb50379 --- /dev/null +++ b/msys2-runtime/0042-cygthread-suspend-thread-before-terminating.patch @@ -0,0 +1,74 @@ +From e09c64ef65cf51011122e55b26abdbda9e70f7e6 Mon Sep 17 00:00:00 2001 +From: Jeremy Drake +Date: Mon, 11 Nov 2024 20:09:49 -0800 +Subject: [PATCH 42/N] cygthread: suspend thread before terminating. + +This addresses an extremely difficult to debug deadlock when running +under emulation on ARM64. + +A relatively easy way to trigger this bug is to call `fork()`, then within the +child process immediately call another `fork()` and then `exit()` the +intermediate process. + +It would seem that there is a "code emulation" lock on the wait thread at +this stage, and if the thread is terminated too early, that lock still exists +albeit without a thread, and nothing moves forward. + +It seems that a `SuspendThread()` combined with a `GetThreadContext()` +(to force the thread to _actually_ be suspended, for more details see +https://devblogs.microsoft.com/oldnewthing/20150205-00/?p=44743) +makes sure the thread is "booted" from emulation before it is suspended. + +Hopefully this means it won't be holding any locks or otherwise leave +emulation in a bad state when the thread is terminated. + +Also, attempt to use `CancelSynchonousIo()` (as seen in `flock.cc`) to avoid +the need for `TerminateThread()` altogether. This doesn't always work, +however, so was not a complete fix for the deadlock issue. + +Addresses: https://cygwin.com/pipermail/cygwin-developers/2024-May/012694.html +Signed-off-by: Jeremy Drake +--- + winsup/cygwin/cygthread.cc | 14 ++++++++++++++ + winsup/cygwin/sigproc.cc | 3 ++- + 2 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc +index 54918e7..4f16097 100644 +--- a/winsup/cygwin/cygthread.cc ++++ b/winsup/cygwin/cygthread.cc +@@ -302,6 +302,20 @@ cygthread::terminate_thread () + if (!inuse) + goto force_notterminated; + ++ if (_my_tls._ctinfo != this) ++ { ++ CONTEXT context; ++ context.ContextFlags = CONTEXT_CONTROL; ++ /* SuspendThread makes sure a thread is "booted" from emulation before ++ it is suspended. As such, the emulator hopefully won't be in a bad ++ state (aka, holding any locks) when the thread is terminated. */ ++ SuspendThread (h); ++ /* We need to call GetThreadContext, even though we don't care about the ++ context, because SuspendThread is asynchronous and GetThreadContext ++ will make sure the thread is *really* suspended before returning */ ++ GetThreadContext (h, &context); ++ } ++ + TerminateThread (h, 0); + WaitForSingleObject (h, INFINITE); + CloseHandle (h); +diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc +index a89f09d..0089626 100644 +--- a/winsup/cygwin/sigproc.cc ++++ b/winsup/cygwin/sigproc.cc +@@ -410,7 +410,8 @@ proc_terminate () + if (!have_execed || !have_execed_cygwin) + chld_procs[i]->ppid = 1; + if (chld_procs[i].wait_thread) +- chld_procs[i].wait_thread->terminate_thread (); ++ if (!CancelSynchronousIo (chld_procs[i].wait_thread->thread_handle ())) ++ chld_procs[i].wait_thread->terminate_thread (); + /* Release memory associated with this process unless it is 'myself'. + 'myself' is only in the chld_procs table when we've execed. We + reach here when the next process has finished initializing but we diff --git a/msys2-runtime/PKGBUILD b/msys2-runtime/PKGBUILD index 0418dee4cb8..f66cf60a6f0 100644 --- a/msys2-runtime/PKGBUILD +++ b/msys2-runtime/PKGBUILD @@ -4,7 +4,7 @@ pkgbase=msys2-runtime pkgname=('msys2-runtime' 'msys2-runtime-devel') pkgver=3.5.4 -pkgrel=3 +pkgrel=4 pkgdesc="Cygwin POSIX emulation engine" arch=('x86_64') url="https://www.cygwin.com/" @@ -69,7 +69,8 @@ source=('msys2-runtime'::git://sourceware.org/git/newlib-cygwin.git#tag=cygwin-$ 0038-Avoid-sharing-cygheaps-across-Cygwin-versions.patch 0039-uname-report-msys2-runtime-commit-hash-too.patch 0040-Cygwin-pipe-Fix-a-regression-that-raw_write-slows-do.patch - 0041-Cygwin-find_fast_cwd-don-t-run-assembler-checking-co.patch) + 0041-Cygwin-find_fast_cwd-don-t-run-assembler-checking-co.patch + 0042-cygthread-suspend-thread-before-terminating.patch) sha256sums=('b8dce32fd9746506752d90ac3f30454fe1689100b08c41442016aaf244cc8584' '9f9e1b6b05cbc9a715fe9443740b25171e9c1a276a058e6ba7e4f6eada6872c8' 'e5b2095e543a5d702cfce6da26cd17a78f40e17620315b1bcc434b94a007ae9b' @@ -111,7 +112,8 @@ sha256sums=('b8dce32fd9746506752d90ac3f30454fe1689100b08c41442016aaf244cc8584' '344f108bc9e9ad597e07f1cc8e834e3d1a9fbd9972a1554c1c5de0fce0ae8506' 'f93578a1150d724a60a7e8eb8491342aeb13f809e2ddb5193d8d126465f665cb' '41e896036ea67c5d12a712554f4d53949c2dc809bb3545ac6be1fe619848f8af' - '34035a411acb71c81a7f4a2367d2cf9f7f00572b6e92c7ba5506e6a48e4867ca') + '34035a411acb71c81a7f4a2367d2cf9f7f00572b6e92c7ba5506e6a48e4867ca' + '6ae29efcd4d17aad01eed252d166de4dd13c0bb2274905933152a1eb21c517dc') # Helper macros to help make tasks easier # apply_patch_with_msg() { @@ -189,7 +191,8 @@ prepare() { 0038-Avoid-sharing-cygheaps-across-Cygwin-versions.patch \ 0039-uname-report-msys2-runtime-commit-hash-too.patch \ 0040-Cygwin-pipe-Fix-a-regression-that-raw_write-slows-do.patch \ - 0041-Cygwin-find_fast_cwd-don-t-run-assembler-checking-co.patch + 0041-Cygwin-find_fast_cwd-don-t-run-assembler-checking-co.patch \ + 0042-cygthread-suspend-thread-before-terminating.patch } build() {