This is the mail archive of the gdb-prs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug python/17314] Any thread created by Python must block SIGCHLD


https://sourceware.org/bugzilla/show_bug.cgi?id=17314

Doug Evans <xdje42 at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |xdje42 at gmail dot com

--- Comment #1 from Doug Evans <xdje42 at gmail dot com> ---
Setting aside the configure.ac changes, here's a prototype patch to forward
SIGCHLD to gdb's thread.

diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 1e8991d..af0cfe2 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -24,9 +24,9 @@
 #include "nat/linux-nat.h"
 #include "nat/linux-waitpid.h"
 #include "gdb_wait.h"
-#ifdef HAVE_TKILL_SYSCALL
-#include <unistd.h>
-#include <sys/syscall.h>
+#if defined (HAVE_TKILL_SYSCALL) || defined (HAVE_GETTID_SYSCALL)
+#include <unistd.h>            /* for syscall */
+#include <sys/syscall.h>       /* for syscall numbers */
 #endif
 #include <sys/ptrace.h>
 #include "linux-nat.h"
@@ -171,6 +171,11 @@ blocked.  */
 #define O_LARGEFILE 0
 #endif

+#ifdef HAVE_GETTID_SYSCALL
+/* The thread id (result of gettid) for gdb.  */
+static pid_t gdb_tid;
+#endif
+
 /* The single-threaded native GNU/Linux target_ops.  We save a pointer for
    the use of the multi-threaded target.  */
 static struct target_ops *linux_ops;
@@ -4664,6 +4673,41 @@ sigchld_handler (int signo)
 {
   int old_errno = errno;

+#ifdef HAVE_GETTID_SYSCALL
+  /* If the user starts other threads (e.g. via python) and if the user
+     doesn't remember to block SIGCHLD in those threads, then that thread
+     may receive the SIGCHLD instead of GDB.  This is bad because gdb will
+     then hang in sigsuspend waiting for the SIGCHLD.  PRs 17247, 17314.
+     If we get a SIGCHLD in a different thread, forward the SIGCHLD onto
+     GDB's thread (if we can).  */     
+  {
+    pid_t this_tid = syscall (__NR_gettid);
+
+    /* IWBN to print an error message here if gettid fails.
+       However, it shouldn't ever fail, and if it does it's possible we'll
+       flood the terminal with failure messages.  Since we're in async code
+       it's harder to clip the output after a certain number of failures,
+       so instead just punt.  */
+#ifdef HAVE_TKILL_SYSCALL
+    if (this_tid > 0 && this_tid != gdb_tid)
+      {
+       if (debug_linux_nat)
+         {
+           static const char forwarding_msg[]
+             = "sigchld: forwarding signal to gdb's thread\n";
+
+           ui_file_write_async_safe (gdb_stdlog, forwarding_msg,
+                                     strlen (forwarding_msg));
+         }
+
+       kill_lwp (gdb_tid, SIGCHLD);
+       errno = old_errno;
+       return;
+      }
+#endif
+  }
+#endif
+
   if (debug_linux_nat)
     ui_file_write_async_safe (gdb_stdlog,
                              "sigchld\n", sizeof ("sigchld\n") - 1);
@@ -5013,6 +5057,12 @@ extern initialize_file_ftype _initialize_linux_nat;
 void
 _initialize_linux_nat (void)
 {
+#ifdef HAVE_GETTID_SYSCALL
+  /* Remember gdb's thread id so that we can perform a sanity check in
+     sigchld_handler.  */
+  gdb_tid = syscall (__NR_gettid);
+#endif
+
   add_setshow_zuinteger_cmd ("lin-lwp", class_maintenance,
                             &debug_linux_nat, _("\
 Set debugging of GNU/Linux lwp module."), _("\

-- 
You are receiving this mail because:
You are on the CC list for the bug.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]