Blame SOURCES/gdb-rhbz1186918-gdbserver-in-container-6of8.patch

01917d
commit 015de6884f6fdebaffd4b7d4c7f14fb4d5fc0bb1
01917d
Author: Daniel Colascione <dancol@dancol.org>
01917d
Date:   Tue Nov 11 14:18:23 2014 +0000
01917d
01917d
    Warn users about mismatched PID namespaces
01917d
    
01917d
    Linux supports multiple "PID namespaces".  Processes in different PID
01917d
    namespaces have different views of the system process list.  Sometimes,
01917d
    a single process can appear in more than one PID namespace, but with a
01917d
    different PID in each.  When GDB and its target are in different PID
01917d
    namespaces, various features can break due to the mismatch between
01917d
    what the target believes its PID to be and what GDB believes its PID
01917d
    to be.  The most visible broken functionality is thread enumeration
01917d
    silently failing.
01917d
    
01917d
    This patch explicitly warns users against trying to debug across PID
01917d
    namespaces.
01917d
    
01917d
    The patch introduced no new failures in my test suite run on an x86_64
01917d
    installation of Ubuntu 14.10.  It doesn't include a test: writing an
01917d
    automated test that exercises this code would be very involved because
01917d
    CLONE_NEWNS requires CAP_SYS_ADMIN; the easier way to reproduce the
01917d
    problem is to start a new lxc container.
01917d
    
01917d
    gdb/
01917d
    2014-11-11  Daniel Colascione  <dancol@dancol.org>
01917d
    
01917d
    	Warn about cross-PID-namespace debugging.
01917d
    	* nat/linux-procfs.h (linux_proc_pid_get_ns): New prototype.
01917d
    	* nat/linux-procfs.c (linux_proc_pid_get_ns): New function.
01917d
    	* linux-thread-db.c (check_pid_namespace_match): New function.
01917d
    	(thread_db_inferior_created): Call it.
01917d
01917d
### a/gdb/ChangeLog
01917d
### b/gdb/ChangeLog
01917d
## -1,3 +1,11 @@
01917d
+2014-11-11  Daniel Colascione  <dancol@dancol.org>
01917d
+
01917d
+	Warn about cross-PID-namespace debugging.
01917d
+	* nat/linux-procfs.h (linux_proc_pid_get_ns): New prototype.
01917d
+	* nat/linux-procfs.c (linux_proc_pid_get_ns): New function.
01917d
+	* linux-thread-db.c (check_pid_namespace_match): New function.
01917d
+	(thread_db_inferior_created): Call it.
01917d
+
01917d
 2014-11-10  Doug Evans  <xdje42@gmail.com>
01917d
 
01917d
 	* symmisc.c (print_objfile_statistics): Remove trailing whitespace.
01917d
Index: gdb-7.6.1/gdb/linux-thread-db.c
01917d
===================================================================
01917d
--- gdb-7.6.1.orig/gdb/linux-thread-db.c	2016-03-17 20:43:34.001735230 +0100
01917d
+++ gdb-7.6.1/gdb/linux-thread-db.c	2016-03-17 21:54:32.233661083 +0100
01917d
@@ -1216,12 +1216,70 @@
01917d
     check_for_thread_db ();
01917d
 }
01917d
 
01917d
+// RHEL: gdb/nat/linux-procfs.h
01917d
+
01917d
+/* Return an opaque string identifying PID's NS namespace or NULL if
01917d
+ * the information is unavailable.  The returned string must be
01917d
+ * released with xfree.  */
01917d
+
01917d
+extern char *linux_proc_pid_get_ns (pid_t pid, const char *ns);
01917d
+
01917d
+// RHEL: gdb/nat/linux-procfs.c
01917d
+
01917d
+/* See linux-procfs.h declaration.  */
01917d
+
01917d
+char *
01917d
+linux_proc_pid_get_ns (pid_t pid, const char *ns)
01917d
+{
01917d
+  char buf[100];
01917d
+  char nsval[64];
01917d
+  int ret;
01917d
+  xsnprintf (buf, sizeof (buf), "/proc/%d/ns/%s", (int) pid, ns);
01917d
+  ret = readlink (buf, nsval, sizeof (nsval));
01917d
+  if (0 < ret && ret < sizeof (nsval))
01917d
+    {
01917d
+      nsval[ret] = '\0';
01917d
+      return xstrdup (nsval);
01917d
+    }
01917d
+
01917d
+  return NULL;
01917d
+}
01917d
+
01917d
+static void
01917d
+check_pid_namespace_match (void)
01917d
+{
01917d
+  /* Check is only relevant for local targets targets.  */
01917d
+  if (target_can_run (&current_target))
01917d
+    {
01917d
+      /* If the child is in a different PID namespace, its idea of its
01917d
+	 PID will differ from our idea of its PID.  When we scan the
01917d
+	 child's thread list, we'll mistakenly think it has no threads
01917d
+	 since the thread PID fields won't match the PID we give to
01917d
+	 libthread_db.  */
01917d
+      char *our_pid_ns = linux_proc_pid_get_ns (getpid (), "pid");
01917d
+      char *inferior_pid_ns = linux_proc_pid_get_ns (
01917d
+	ptid_get_pid (inferior_ptid), "pid");
01917d
+
01917d
+      if (our_pid_ns != NULL && inferior_pid_ns != NULL
01917d
+	  && strcmp (our_pid_ns, inferior_pid_ns) != 0)
01917d
+	{
01917d
+	  warning (_ ("Target and debugger are in different PID "
01917d
+		      "namespaces; thread lists and other data are "
01917d
+		      "likely unreliable"));
01917d
+	}
01917d
+
01917d
+      xfree (our_pid_ns);
01917d
+      xfree (inferior_pid_ns);
01917d
+    }
01917d
+}
01917d
+
01917d
 /* This function is called via the inferior_created observer.
01917d
    This handles the case of debugging statically linked executables.  */
01917d
 
01917d
 static void
01917d
 thread_db_inferior_created (struct target_ops *target, int from_tty)
01917d
 {
01917d
+  check_pid_namespace_match ();
01917d
   check_for_thread_db ();
01917d
 }
01917d