[newlib-cygwin] Cygwin: timerfd: fix shared memory allocation in fork/exec

Corinna Vinschen corinna@sourceware.org
Sun Feb 24 19:49:00 GMT 2019


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=a4e2eb6ba34b8cd3457e7f4074b1725874d6e2e9

commit a4e2eb6ba34b8cd3457e7f4074b1725874d6e2e9
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Sun Feb 24 20:15:36 2019 +0100

    Cygwin: timerfd: fix shared memory allocation in fork/exec
    
    timerfd_tracker::fixup_after_fork_exec always tries to restore
    the shared timer region at the same address as in the parent.
    This is entirely unnecessary and wasn't intended, rather some
    kind of copy/paste thinko.  Fix that.  Print NtMapViewOfSection
    status code in api_fatal on failure for debugging.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/release/3.0.2 |  3 +++
 winsup/cygwin/timerfd.cc    | 14 ++++++++------
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/winsup/cygwin/release/3.0.2 b/winsup/cygwin/release/3.0.2
index c1a18a9..e24fe4e 100644
--- a/winsup/cygwin/release/3.0.2
+++ b/winsup/cygwin/release/3.0.2
@@ -12,6 +12,9 @@ Bug Fixes
 - Fix timerfd select always returning immediately.
   Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00364.html
 
+- Fix fork/exec failing to restore timerfd share mem in child process.
+  Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00400.html
+
 - Drop enforcing case-correct group names for AD accounts to avoid
   excessively long startup times.
   Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00301.html
diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc
index 7e6be72..2823560 100644
--- a/winsup/cygwin/timerfd.cc
+++ b/winsup/cygwin/timerfd.cc
@@ -408,6 +408,7 @@ void
 timerfd_tracker::fixup_after_fork_exec (bool execing)
 {
   NTSTATUS status;
+  PVOID base_address = NULL;
   OBJECT_ATTRIBUTES attr;
   SIZE_T vsize = PAGE_SIZE;
 
@@ -416,11 +417,12 @@ timerfd_tracker::fixup_after_fork_exec (bool execing)
     return;
   /* Recreate shared section mapping */
   status = NtMapViewOfSection (tfd_shared_hdl, NtCurrentProcess (),
-			       (void **) &tfd_shared, 0, PAGE_SIZE, NULL,
-			       &vsize, ViewShare, MEM_TOP_DOWN, PAGE_READWRITE);
+			       &base_address, 0, PAGE_SIZE, NULL,
+			       &vsize, ViewShare, 0, PAGE_READWRITE);
   if (!NT_SUCCESS (status))
-    api_fatal ("Can't recreate shared timerfd section during %s!",
-	       execing ? "execve" : "fork");
+    api_fatal ("Can't recreate shared timerfd section during %s, status %y!",
+	       execing ? "execve" : "fork", status);
+  tfd_shared = (timerfd_shared *) base_address;
   /* Increment global instance count by the number of instances in this
      process */
   InterlockedAdd (&tfd_shared->instance_count, local_instance_count);
@@ -430,8 +432,8 @@ timerfd_tracker::fixup_after_fork_exec (bool execing)
   status = NtCreateEvent (&cancel_evt, EVENT_ALL_ACCESS, &attr,
 			  NotificationEvent, FALSE);
   if (!NT_SUCCESS (status))
-    api_fatal ("Can't recreate timerfd cancel event during %s!",
-	       execing ? "execve" : "fork");
+    api_fatal ("Can't recreate timerfd cancel event during %s, status %y!",
+	       execing ? "execve" : "fork", status);
   /* Set winpid so we don't run this twice */
   winpid = GetCurrentProcessId ();
   new cygthread (timerfd_thread, this, "timerfd", sync_thr);



More information about the Cygwin-cvs mailing list