GNU bug report logs - #43066
Hang when forking new process.

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: guile; Reported by: Mathieu Othacehe <othacehe@HIDDEN>; dated Thu, 27 Aug 2020 07:43:01 UTC; Maintainer for guile is bug-guile@HIDDEN.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 27 Aug 2020 07:42:52 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Aug 27 03:42:52 2020
Received: from localhost ([127.0.0.1]:41470 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1kBCYe-0002pG-Jf
	for submit <at> debbugs.gnu.org; Thu, 27 Aug 2020 03:42:52 -0400
Received: from lists.gnu.org ([209.51.188.17]:53810)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <othacehe@HIDDEN>) id 1kBCYb-0002p7-Uj
 for submit <at> debbugs.gnu.org; Thu, 27 Aug 2020 03:42:51 -0400
Received: from eggs.gnu.org ([2001:470:142:3::10]:34814)
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <othacehe@HIDDEN>) id 1kBCYb-0008Qw-Nl
 for bug-guile@HIDDEN; Thu, 27 Aug 2020 03:42:49 -0400
Received: from fencepost.gnu.org ([2001:470:142:3::e]:48011)
 by eggs.gnu.org with esmtp (Exim 4.90_1)
 (envelope-from <othacehe@HIDDEN>) id 1kBCYb-0007jG-Fh
 for bug-guile@HIDDEN; Thu, 27 Aug 2020 03:42:49 -0400
Received: from [2a01:e0a:19b:d9a0:d1f2:1c2d:9e7a:dd0] (port=51724 helo=cervin)
 by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256)
 (Exim 4.82) (envelope-from <othacehe@HIDDEN>) id 1kBCYb-0007YS-2z
 for bug-guile@HIDDEN; Thu, 27 Aug 2020 03:42:49 -0400
From: Mathieu Othacehe <othacehe@HIDDEN>
To: bug-guile@HIDDEN
Subject: Hang when forking new process.
Date: Thu, 27 Aug 2020 09:42:47 +0200
Message-ID: <87r1rsh6vc.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
X-Spam-Score: -2.3 (--)
X-Debbugs-Envelope-To: submit
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

--=-=-=
Content-Type: text/plain


Hello,

When forking, the finalization pipe file descriptors are
inherited. If the child process spawns a finalization thread, it will
use a copy of its parent finalization pipe file descriptors.

Hence, if the parent tries to stop its finalization thread, by forking
another process for instance, it may stop the child finalization thread
and hang forever waiting for its own finalization thread to stop.

Here's a small reproducer attached. On my machine, the program hangs
around iteration 100. Note that this has previously been discussed
here[1].

The attached patch should fix this by closing the finalization pipe file
descriptor copies in the child right after forking and opening a new
pipe by calling scm_init_finalizer_thread.

Thanks,

Mathieu

[1]: https://issues.guix.gnu.org/41948

--=-=-=
Content-Type: application/octet-stream
Content-Disposition: attachment; filename=t.scm
Content-Transfer-Encoding: base64

KHVzZS1tb2R1bGVzIChpY2UtOSBtYXRjaCkpCgooZGVmaW5lIChzdGFydC1wcm9jZXNzIGNvbW1h
bmQpCiAgKG1hdGNoIChwcmltaXRpdmUtZm9yaykKICAgICgwCiAgICAgKGV4ZWNsICIvYmluL3No
IiAic2giICItYyIgY29tbWFuZCkpCiAgICAoXyAjdCkpKQoKKG1hdGNoIChwcmltaXRpdmUtZm9y
aykKICAoMAogICAod2hpbGUgI3QKICAgICAoZ2MpCiAgICAgKHVzbGVlcCAyMDAwMDApKSkKICAo
cGlkCiAgIChsZXQgbG9vcCAoKGNvdW50IDApKQogICAgIChmb3JtYXQgI3QgIkZvcmtpbmcgfmF+
JSIgY291bnQpCiAgICAgKHN0YXJ0LXByb2Nlc3MgInNsZWVwIDEiKQogICAgICh1c2xlZXAgKHJh
bmRvbSAyMDAwMDApKQogICAgIChsb29wICgxKyBjb3VudCkpKSkpCg==
--=-=-=
Content-Type: text/x-diff
Content-Disposition: inline;
 filename=0001-Close-finalization-pipe-after-forking.patch

From 004c0c78c9c21c48b38d76b5d7b356b40c8e5a4a Mon Sep 17 00:00:00 2001
From: Mathieu Othacehe <othacehe@HIDDEN>
Date: Thu, 27 Aug 2020 09:16:55 +0200
Subject: [PATCH] Close finalization pipe after forking.

When forking, the finalization pipe file descriptors are
inherited. If the child process spawns a finalization thread, it will
use a copy of its parent finalization pipe file descriptors.

Hence, if the parent tries to stop its finalization thread, by forking
another process for instance, it may stop the child finalization thread
and hang forever for its own finalization thread to stop.

Fix it by closing the finalization pipe file descriptor copies in the
child right after forking and opening a new pipe by calling
scm_init_finalizer_thread.

* libguile/finalizers.c (scm_i_finalizer_post_fork): New function.
* libguile/finalizers.c (scm_i_finalizer_post_fork): Declare it.
* libguile/posix.c (scm_fork): Call it in the child process, right after forking.
---
 libguile/finalizers.c | 13 +++++++++++++
 libguile/finalizers.h |  1 +
 libguile/posix.c      |  4 ++++
 3 files changed, 18 insertions(+)

diff --git a/libguile/finalizers.c b/libguile/finalizers.c
index 0ae165fd1..b1803b34b 100644
--- a/libguile/finalizers.c
+++ b/libguile/finalizers.c
@@ -305,6 +305,19 @@ scm_i_finalizer_pre_fork (void)
 #endif
 }
 
+void
+scm_i_finalizer_post_fork (void)
+{
+#if SCM_USE_PTHREAD_THREADS
+  if (automatic_finalization_p)
+    {
+      close (finalization_pipe[0]);
+      close (finalization_pipe[1]);
+      scm_init_finalizer_thread ();
+    }
+#endif
+}
+
 
 
 
diff --git a/libguile/finalizers.h b/libguile/finalizers.h
index 44bafb22e..866e4d1eb 100644
--- a/libguile/finalizers.h
+++ b/libguile/finalizers.h
@@ -36,6 +36,7 @@ SCM_INTERNAL void scm_i_add_resuscitator (void *obj, scm_t_finalizer_proc,
                                           void *data);
 
 SCM_INTERNAL void scm_i_finalizer_pre_fork (void);
+SCM_INTERNAL void scm_i_finalizer_post_fork  (void);
 
 /* CALLBACK will be called after each garbage collection.  It will be
    called from a finalizer, which may be from an async or from another
diff --git a/libguile/posix.c b/libguile/posix.c
index 47769003a..022bda6e3 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -1247,6 +1247,10 @@ SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
   pid = fork ();
   if (pid == -1)
     SCM_SYSERROR;
+
+  if (!pid)
+    scm_i_finalizer_post_fork ();
+
   return scm_from_int (pid);
 }
 #undef FUNC_NAME
-- 
2.28.0


--=-=-=--




Acknowledgement sent to Mathieu Othacehe <othacehe@HIDDEN>:
New bug report received and forwarded. Copy sent to bug-guile@HIDDEN. Full text available.
Report forwarded to bug-guile@HIDDEN:
bug#43066; Package guile. Full text available.
Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.
Last modified: Thu, 27 Aug 2020 07:45:01 UTC

GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997 nCipher Corporation Ltd, 1994-97 Ian Jackson.