From unknown Sat Aug 16 21:23:56 2025 X-Loop: help-debbugs@gnu.org Subject: bug#43066: Hang when forking new process. Resent-From: Mathieu Othacehe Original-Sender: "Debbugs-submit" Resent-CC: bug-guile@gnu.org Resent-Date: Thu, 27 Aug 2020 07:43:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 43066 X-GNU-PR-Package: guile X-GNU-PR-Keywords: To: 43066@debbugs.gnu.org X-Debbugs-Original-To: bug-guile@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.159851417210870 (code B ref -1); Thu, 27 Aug 2020 07:43:01 +0000 Received: (at submit) by debbugs.gnu.org; 27 Aug 2020 07:42:52 +0000 Received: from localhost ([127.0.0.1]:41470 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kBCYe-0002pG-Jf for submit@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 ) id 1kBCYb-0002p7-Uj for submit@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 ) id 1kBCYb-0008Qw-Nl for bug-guile@gnu.org; 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 ) id 1kBCYb-0007jG-Fh for bug-guile@gnu.org; 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 ) id 1kBCYb-0007YS-2z for bug-guile@gnu.org; Thu, 27 Aug 2020 03:42:49 -0400 From: Mathieu Othacehe Date: Thu, 27 Aug 2020 09:42:47 +0200 Message-ID: <87r1rsh6vc.fsf@gnu.org> 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-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" 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 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 --=-=-=-- From unknown Sat Aug 16 21:23:56 2025 MIME-Version: 1.0 X-Mailer: MIME-tools 5.505 (Entity 5.505) X-Loop: help-debbugs@gnu.org From: help-debbugs@gnu.org (GNU bug Tracking System) To: Mathieu Othacehe Subject: bug#43066: closed (Re: bug#43066: Hang when forking new process.) Message-ID: References: <87mtt11rfu.fsf@gnu.org> <87r1rsh6vc.fsf@gnu.org> X-Gnu-PR-Message: they-closed 43066 X-Gnu-PR-Package: guile Reply-To: 43066@debbugs.gnu.org Date: Tue, 11 May 2021 10:44:02 +0000 Content-Type: multipart/mixed; boundary="----------=_1620729842-23340-1" This is a multi-part message in MIME format... ------------=_1620729842-23340-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Your bug report #43066: Hang when forking new process. which was filed against the guile package, has been closed. The explanation is attached below, along with your original report. If you require more details, please reply to 43066@debbugs.gnu.org. --=20 43066: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D43066 GNU Bug Tracking System Contact help-debbugs@gnu.org with problems ------------=_1620729842-23340-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at 43066-done) by debbugs.gnu.org; 11 May 2021 10:43:41 +0000 Received: from localhost ([127.0.0.1]:35134 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lgPrZ-00063k-GS for submit@debbugs.gnu.org; Tue, 11 May 2021 06:43:41 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33550) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lgPrX-00063X-Uv for 43066-done@debbugs.gnu.org; Tue, 11 May 2021 06:43:40 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:45098) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lgPrS-0002zu-MT for 43066-done@debbugs.gnu.org; Tue, 11 May 2021 06:43:34 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=41916 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lgPrS-0007DL-DM; Tue, 11 May 2021 06:43:34 -0400 From: =?utf-8?Q?Ludovic_Court=C3=A8s?= To: Mathieu Othacehe Subject: Re: bug#43066: Hang when forking new process. References: <87r1rsh6vc.fsf@gnu.org> Date: Tue, 11 May 2021 12:43:33 +0200 In-Reply-To: <87r1rsh6vc.fsf@gnu.org> (Mathieu Othacehe's message of "Thu, 27 Aug 2020 09:42:47 +0200") Message-ID: <87mtt11rfu.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 43066-done Cc: 43066-done@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Hi Mathieu, Mathieu Othacehe skribis: >>>From 004c0c78c9c21c48b38d76b5d7b356b40c8e5a4a Mon Sep 17 00:00:00 2001 > From: Mathieu Othacehe > 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. Apologies for overlooking this patch! This was fixed differently in 5a281e35f4a5ae78fbcf10591d9358bec8f0bee0, which is in 3.0.7. Thanks, Ludo=E2=80=99. ------------=_1620729842-23340-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at submit) by debbugs.gnu.org; 27 Aug 2020 07:42:52 +0000 Received: from localhost ([127.0.0.1]:41470 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kBCYe-0002pG-Jf for submit@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 ) id 1kBCYb-0002p7-Uj for submit@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 ) id 1kBCYb-0008Qw-Nl for bug-guile@gnu.org; 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 ) id 1kBCYb-0007jG-Fh for bug-guile@gnu.org; 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 ) id 1kBCYb-0007YS-2z for bug-guile@gnu.org; Thu, 27 Aug 2020 03:42:49 -0400 From: Mathieu Othacehe To: bug-guile@gnu.org Subject: Hang when forking new process. Date: Thu, 27 Aug 2020 09:42:47 +0200 Message-ID: <87r1rsh6vc.fsf@gnu.org> 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@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" 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 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 --=-=-=-- ------------=_1620729842-23340-1--