unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Need to block SIGCHLD in libgc and guile internal threads
@ 2014-08-26  8:14 Doug Evans
  2014-08-26 16:41 ` Doug Evans
  2014-08-29 17:36 ` mhw
  0 siblings, 2 replies; 4+ messages in thread
From: Doug Evans @ 2014-08-26  8:14 UTC (permalink / raw)
  To: guile-devel

Hi.

I think(!) I understand why gdb is hanging when used with libgc 7.4.x.
This is gdb bug 17247.
https://sourceware.org/bugzilla/show_bug.cgi?id=17247#c30

First, libgc 7.4.x was the first release to default PARALLEL_MARK to
on, so I'm guessing the same "bug" exists in 7.2, it's just not
visible unless one builds libgc with --enable-parallel-mark.

gdb/linux-nat.c calls sigsuspend when the inferior is running and gdb
needs to wait for it to stop.
gdb is waiting on a SIGCHLD at this point.

However, if the SIGCHLD goes to a different thread, say the guile
finalizer thread or a libgc marker thread then the sigsuspend that gdb
calls doesn't wake up and gdb is hung.

So question: Any suggestions for how to approach this?

Here's the hack that I applied to Guile to see if this removes the gdb hang.
I'm not suggesting checking this in.  It's just data to help advance
the discussion.
I think there's a general issue here that these threads should block
every signal
they're not expecting, or at least provide a hook to let the app
specify which signals
to block.  gdb's need to use SIGCHLD is just one example of a general problem.

diff --git a/libguile/finalizers.c b/libguile/finalizers.c
index 82f292c..95a022c 100644
--- a/libguile/finalizers.c
+++ b/libguile/finalizers.c
@@ -239,6 +239,12 @@ finalization_thread_proc (void *unused)
 static void*
 run_finalization_thread (void *arg)
 {
+  {
+    sigset_t blocked_mask;
+    sigemptyset (&blocked_mask);
+    sigaddset (&blocked_mask, SIGCHLD);
+    sigprocmask (SIG_BLOCK, &blocked_mask, NULL);
+  }
   return scm_with_guile (finalization_thread_proc, arg);
 }



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: Need to block SIGCHLD in libgc and guile internal threads
  2014-08-26  8:14 Need to block SIGCHLD in libgc and guile internal threads Doug Evans
@ 2014-08-26 16:41 ` Doug Evans
  2014-08-29 17:36 ` mhw
  1 sibling, 0 replies; 4+ messages in thread
From: Doug Evans @ 2014-08-26 16:41 UTC (permalink / raw)
  To: guile-devel

On Tue, Aug 26, 2014 at 1:14 AM, Doug Evans <xdje42@gmail.com> wrote:
> Hi.
>
> I think(!) I understand why gdb is hanging when used with libgc 7.4.x.
> This is gdb bug 17247.
> https://sourceware.org/bugzilla/show_bug.cgi?id=17247#c30
>
> First, libgc 7.4.x was the first release to default PARALLEL_MARK to
> on, so I'm guessing the same "bug" exists in 7.2, it's just not
> visible unless one builds libgc with --enable-parallel-mark.
>
> gdb/linux-nat.c calls sigsuspend when the inferior is running and gdb
> needs to wait for it to stop.
> gdb is waiting on a SIGCHLD at this point.
>
> However, if the SIGCHLD goes to a different thread, say the guile
> finalizer thread or a libgc marker thread then the sigsuspend that gdb
> calls doesn't wake up and gdb is hung.
>
> So question: Any suggestions for how to approach this?

Since threads inherit the sigmask of their creator one thing I could
do, I think, is block SIGCHLD before initializing Guile and then
unblock it afterwards.  The four threads I see being created during
Guile initialization (3 marker threads plus Guile's finalizer thread)
are created during that time.

Question: Does Guile create any threads lazily?

[I'm referring to internal Guile-created threads.
Users who create their own threads are on their own,
at least for now. IWBN though if there were a mechanism
to have all threads that Guile created have SIGCHLD
initially blocked.  I wouildn't make it SIGCHLD-specific
of course - just have a way to augment the initial
sigmask of newly created threads.]



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Need to block SIGCHLD in libgc and guile internal threads
  2014-08-26  8:14 Need to block SIGCHLD in libgc and guile internal threads Doug Evans
  2014-08-26 16:41 ` Doug Evans
@ 2014-08-29 17:36 ` mhw
  2014-08-30 17:40   ` Doug Evans
  1 sibling, 1 reply; 4+ messages in thread
From: mhw @ 2014-08-29 17:36 UTC (permalink / raw)
  To: Doug Evans; +Cc: guile-devel

Doug Evans <xdje42@gmail.com> writes:

> I think(!) I understand why gdb is hanging when used with libgc 7.4.x.
> This is gdb bug 17247.
> https://sourceware.org/bugzilla/show_bug.cgi?id=17247#c30

[...]

> gdb/linux-nat.c calls sigsuspend when the inferior is running and gdb
> needs to wait for it to stop.
> gdb is waiting on a SIGCHLD at this point.
>
> However, if the SIGCHLD goes to a different thread, say the guile
> finalizer thread or a libgc marker thread then the sigsuspend that gdb
> calls doesn't wake up and gdb is hung.
>
> So question: Any suggestions for how to approach this?

[...]

> I think there's a general issue here that these threads should block
> every signal they're not expecting,

Agreed.  Threads that Guile creates implicitly should block every signal
that they're not expecting.

> diff --git a/libguile/finalizers.c b/libguile/finalizers.c
> index 82f292c..95a022c 100644
> --- a/libguile/finalizers.c
> +++ b/libguile/finalizers.c
> @@ -239,6 +239,12 @@ finalization_thread_proc (void *unused)
>  static void*
>  run_finalization_thread (void *arg)
>  {
> +  {
> +    sigset_t blocked_mask;
> +    sigemptyset (&blocked_mask);
> +    sigaddset (&blocked_mask, SIGCHLD);
> +    sigprocmask (SIG_BLOCK, &blocked_mask, NULL);
> +  }
>    return scm_with_guile (finalization_thread_proc, arg);
>  }

This code should be harmonized with the code at the top of
'signal_delivery_thread' in scmsigs.c:

--8<---------------cut here---------------start------------->8---
static SCM
signal_delivery_thread (void *data)
{
  int sig;
#if HAVE_PTHREAD_SIGMASK  /* not on mingw, see notes above */
  sigset_t all_sigs;
  sigfillset (&all_sigs);
  /* On libgc 7.1 and earlier, GC_do_blocking doesn't actually do
     anything.  So in that case, libgc will want to suspend the signal
     delivery thread, so we need to allow it to do so by unmasking the
     suspend signal.  */
  sigdelset (&all_sigs, GC_get_suspend_signal ());
  scm_i_pthread_sigmask (SIG_SETMASK, &all_sigs, NULL);
#endif
--8<---------------cut here---------------end--------------->8---

On master, where we now require gc-7.2 or later, I guess we should be
able to simplify this and block all signals.

However, it's not clear how to backport this to stable-2.0, which does
not even have a finalization thread, and yet gdb bug 17247 occurs with
Guile 2.0.11.  Any idea how to prevent the problem on stable-2.0?

     Thanks,
       Mark



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Need to block SIGCHLD in libgc and guile internal threads
  2014-08-29 17:36 ` mhw
@ 2014-08-30 17:40   ` Doug Evans
  0 siblings, 0 replies; 4+ messages in thread
From: Doug Evans @ 2014-08-30 17:40 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guile-devel

On Fri, Aug 29, 2014 at 10:36 AM,  <mhw@netris.org> wrote:
> On master, where we now require gc-7.2 or later, I guess we should be
> able to simplify this and block all signals.
>
> However, it's not clear how to backport this to stable-2.0, which does
> not even have a finalization thread, and yet gdb bug 17247 occurs with
> Guile 2.0.11.  Any idea how to prevent the problem on stable-2.0?

For gdb my plan is to block SIGCHLD before initializing guile and
unblock it afterwards.
That'll work regardless of guile version (assuming no new internal
guile threads get created afterwards).
For stable-2.0 you could do a similar thing I guess: block every
signal not expected before
initializing libgc and undo that afterwards.
[taking care to not block signals libgc uses internally I guess,
e.g. SIGPWR, SIGXCPU. I'm not sure if libgc checks and fails
to initialize or unblocks them]
[and, for completeness sake, we're only talking about asynchronous
signals ... not SIGSEGV, etc.]



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-08-30 17:40 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-26  8:14 Need to block SIGCHLD in libgc and guile internal threads Doug Evans
2014-08-26 16:41 ` Doug Evans
2014-08-29 17:36 ` mhw
2014-08-30 17:40   ` Doug Evans

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).