[newlib-cygwin/cygwin-3_6-branch] Cygwin: fork: Call pthread::atforkchild () after other initializations
Takashi Yano
tyan0@sourceware.org
Sat Apr 5 15:29:22 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=e0bd8b4f9b7e01f852350ac8ec09166723a96871
commit e0bd8b4f9b7e01f852350ac8ec09166723a96871
Author: Takashi Yano <takashi.yano@nifty.ne.jp>
Date: Thu Apr 3 15:22:29 2025 +0900
Cygwin: fork: Call pthread::atforkchild () after other initializations
Previously, the callback registered by pthread_atfork() was called
in pthread::atforkchild() before _my_tls.fixup_after_fork(). This
caused misbehaviour if the callback used TLS-related functions.
More specifically, cygwait() for a mutex at the beginning of
fhandler_fifo_pipe::raw_write() failed because the event handle
_my_tls.signal_arrived, which is used in cygwait() internally and
designed to be initialized in _cygtls::fixup_after_fork(), was not
yet initialized at that point. Due to this problem, subprocesses
of CMake (versions >= 3.29.x) sometimes failed after the commit
7ed9adb356df ("Cygwin: pipe: Switch pipe mode to blocking mode by
default, 2024-09-05"). This commit triggered the issue because it
introduced cygwait() for the mutex in fhandler_fifo_pipe::raw_write().
This patch moves the pthread::atforkchild() at the end of the fork::
child(), i.e. after all initializations for child process is finished.
The reason why the issue happens not always but sometimes:
The event handle signal_arrived was never properly initialized when
fhandler_fifo_pipe::raw_write() was called from the callback. As a
result, its value was merely copied from the parent process during
a fork() operation. Since the event signal_arrived was not created
as inheritable, the handle value was fundamentally invalid. Despite
this, the issue only occurred occasionally. This inconsistency was
due to the handle value often coinciding with other existing handles
because of its small value, such as 0x1ac. As evidence of this, in
many cases where the issue did not manifest, the signal_arrived
handle was not even an event handle.
Addresses: https://cygwin.com/pipermail/cygwin/2025-March/257800.html
Addresses: https://github.com/msys2/msys2-runtime/issues/272
Fixes: f02b22dcee17 ("* fork.cc (frok::child): Change order of cleanup prior to return.")
Reported-by: Christoph Reiter <reiter.christoph@gmail.com>
Reviewed-by: Jeremy Drake <cygwin@jdrake.com>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
(cherry picked from commit 779e46b5b3ee8d0250f084d1cf2d68c0483a521e)
Diff:
---
winsup/cygwin/fork.cc | 2 +-
winsup/cygwin/release/3.6.1 | 5 +++++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 783971b76..f88acdbbf 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -187,7 +187,6 @@ frok::child (volatile char * volatile here)
ForceCloseHandle1 (fork_info->forker_finished, forker_finished);
- pthread::atforkchild ();
cygbench ("fork-child");
ld_preload ();
fixup_hooks_after_fork ();
@@ -199,6 +198,7 @@ frok::child (volatile char * volatile here)
CloseHandle (hParent);
hParent = NULL;
cygwin_finished_initializing = true;
+ pthread::atforkchild ();
return 0;
}
diff --git a/winsup/cygwin/release/3.6.1 b/winsup/cygwin/release/3.6.1
index 07a29ecce..c09a23376 100644
--- a/winsup/cygwin/release/3.6.1
+++ b/winsup/cygwin/release/3.6.1
@@ -31,3 +31,8 @@ Fixes:
- Return EMFILE when opening /dev/ptmx too many times.
Addresses: https://cygwin.com/pipermail/cygwin/2025-March/257786.html
+
+- Move pthread::atforkchild() at the end of fork::child(). This fixes
+ subprocess failure in cmake (>= 3.29.x).
+ Addresses: https://cygwin.com/pipermail/cygwin/2025-March/257800.html
+ Addresses: https://github.com/msys2/msys2-runtime/issues/272
More information about the Cygwin-cvs
mailing list