Don't always build coffgen.o
[deliverable/binutils-gdb.git] / gdb / linux-thread-db.c
index ca614a3e72ff3dcba00e9379a9628ae305959d88..c49b5674c4fd3adbb28a86fb99905cd9eb71c0d9 100644 (file)
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-
-#include "gdb_assert.h"
 #include <dlfcn.h>
 #include "gdb_proc_service.h"
-#include "gdb_thread_db.h"
+#include "nat/gdb_thread_db.h"
 #include "gdb_vecs.h"
 #include "bfd.h"
 #include "command.h"
-#include "exceptions.h"
 #include "gdbcmd.h"
 #include "gdbthread.h"
 #include "inferior.h"
+#include "infrun.h"
 #include "symfile.h"
 #include "objfiles.h"
 #include "target.h"
@@ -39,8 +37,8 @@
 #include "gdbcore.h"
 #include "observer.h"
 #include "linux-nat.h"
-#include "linux-procfs.h"
-#include "linux-osdata.h"
+#include "nat/linux-procfs.h"
+#include "nat/linux-osdata.h"
 #include "auto-load.h"
 #include "cli/cli-utils.h"
 
@@ -196,6 +194,9 @@ struct thread_db_info
   td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
                                     psaddr_t map_address,
                                     size_t offset, psaddr_t *address);
+  td_err_e (*td_thr_tlsbase_p) (const td_thrhandle_t *th,
+                               unsigned long int modid,
+                               psaddr_t *base);
 };
 
 /* List of known processes using thread_db, and the required
@@ -799,6 +800,7 @@ try_thread_db_load_1 (struct thread_db_info *info)
   info->td_ta_event_getmsg_p = dlsym (info->handle, "td_ta_event_getmsg");
   info->td_thr_event_enable_p = dlsym (info->handle, "td_thr_event_enable");
   info->td_thr_tls_get_addr_p = dlsym (info->handle, "td_thr_tls_get_addr");
+  info->td_thr_tlsbase_p = dlsym (info->handle, "td_thr_tlsbase");
 
   if (thread_db_find_new_threads_silently (inferior_ptid) != 0)
     {
@@ -1215,12 +1217,41 @@ thread_db_new_objfile (struct objfile *objfile)
     check_for_thread_db ();
 }
 
+static void
+check_pid_namespace_match (void)
+{
+  /* Check is only relevant for local targets targets.  */
+  if (target_can_run (&current_target))
+    {
+      /* If the child is in a different PID namespace, its idea of its
+        PID will differ from our idea of its PID.  When we scan the
+        child's thread list, we'll mistakenly think it has no threads
+        since the thread PID fields won't match the PID we give to
+        libthread_db.  */
+      char *our_pid_ns = linux_proc_pid_get_ns (getpid (), "pid");
+      char *inferior_pid_ns = linux_proc_pid_get_ns (
+       ptid_get_pid (inferior_ptid), "pid");
+
+      if (our_pid_ns != NULL && inferior_pid_ns != NULL
+         && strcmp (our_pid_ns, inferior_pid_ns) != 0)
+       {
+         warning (_ ("Target and debugger are in different PID "
+                     "namespaces; thread lists and other data are "
+                     "likely unreliable"));
+       }
+
+      xfree (our_pid_ns);
+      xfree (inferior_pid_ns);
+    }
+}
+
 /* This function is called via the inferior_created observer.
    This handles the case of debugging statically linked executables.  */
 
 static void
 thread_db_inferior_created (struct target_ops *target, int from_tty)
 {
+  check_pid_namespace_match ();
   check_for_thread_db ();
 }
 
@@ -1715,11 +1746,13 @@ update_thread_core (struct lwp_info *info, void *closure)
 }
 
 static void
-thread_db_find_new_threads (struct target_ops *ops)
+thread_db_update_thread_list (struct target_ops *ops)
 {
   struct thread_db_info *info;
   struct inferior *inf;
 
+  prune_threads ();
+
   ALL_INFERIORS (inf)
     {
       struct thread_info *thread;
@@ -1762,10 +1795,7 @@ thread_db_pid_to_str (struct target_ops *ops, ptid_t ptid)
     }
 
   beneath = find_target_beneath (ops);
-  if (beneath->to_pid_to_str (beneath, ptid))
-    return beneath->to_pid_to_str (beneath, ptid);
-
-  return normal_pid_to_str (ptid);
+  return beneath->to_pid_to_str (beneath, ptid);
 }
 
 /* Return a string describing the state of the thread specified by
@@ -1811,21 +1841,39 @@ thread_db_get_thread_local_address (struct target_ops *ops,
 
       info = get_thread_db_info (ptid_get_pid (ptid));
 
-      /* glibc doesn't provide the needed interface.  */
-      if (!info->td_thr_tls_get_addr_p)
-       throw_error (TLS_NO_LIBRARY_SUPPORT_ERROR,
-                    _("No TLS library support"));
-
-      /* Caller should have verified that lm != 0.  */
-      gdb_assert (lm != 0);
-
       /* Finally, get the address of the variable.  */
-      /* Note the cast through uintptr_t: this interface only works if
-        a target address fits in a psaddr_t, which is a host pointer.
-        So a 32-bit debugger can not access 64-bit TLS through this.  */
-      err = info->td_thr_tls_get_addr_p (&thread_info->private->th,
-                                        (psaddr_t)(uintptr_t) lm,
-                                        offset, &address);
+      if (lm != 0)
+       {
+         /* glibc doesn't provide the needed interface.  */
+         if (!info->td_thr_tls_get_addr_p)
+           throw_error (TLS_NO_LIBRARY_SUPPORT_ERROR,
+                        _("No TLS library support"));
+
+         /* Note the cast through uintptr_t: this interface only works if
+            a target address fits in a psaddr_t, which is a host pointer.
+            So a 32-bit debugger can not access 64-bit TLS through this.  */
+         err = info->td_thr_tls_get_addr_p (&thread_info->private->th,
+                                            (psaddr_t)(uintptr_t) lm,
+                                            offset, &address);
+       }
+      else
+       {
+         /* If glibc doesn't provide the needed interface throw an error
+            that LM is zero - normally cases it should not be.  */
+         if (!info->td_thr_tlsbase_p)
+           throw_error (TLS_LOAD_MODULE_NOT_FOUND_ERROR,
+                        _("TLS load module not found"));
+
+         /* This code path handles the case of -static -pthread executables:
+            https://sourceware.org/ml/libc-help/2014-03/msg00024.html
+            For older GNU libc r_debug.r_map is NULL.  For GNU libc after
+            PR libc/16831 due to GDB PR threads/16954 LOAD_MODULE is also NULL.
+            The constant number 1 depends on GNU __libc_setup_tls
+            initialization of l_tls_modid to 1.  */
+         err = info->td_thr_tlsbase_p (&thread_info->private->th,
+                                       1, &address);
+         address = (char *) address + offset;
+       }
 
 #ifdef THREAD_DB_HAS_TD_NOTALLOC
       /* The memory hasn't been allocated, yet.  */
@@ -1851,11 +1899,7 @@ thread_db_get_thread_local_address (struct target_ops *ops,
     }
 
   beneath = find_target_beneath (ops);
-  if (beneath->to_get_thread_local_address)
-    return beneath->to_get_thread_local_address (beneath, ptid, lm, offset);
-  else
-    throw_error (TLS_GENERIC_ERROR,
-                _("TLS not supported on this target"));
+  return beneath->to_get_thread_local_address (beneath, ptid, lm, offset);
 }
 
 /* Callback routine used to find a thread based on the TID part of
@@ -2061,7 +2105,7 @@ init_thread_db_ops (void)
   thread_db_ops.to_wait = thread_db_wait;
   thread_db_ops.to_resume = thread_db_resume;
   thread_db_ops.to_mourn_inferior = thread_db_mourn_inferior;
-  thread_db_ops.to_find_new_threads = thread_db_find_new_threads;
+  thread_db_ops.to_update_thread_list = thread_db_update_thread_list;
   thread_db_ops.to_pid_to_str = thread_db_pid_to_str;
   thread_db_ops.to_stratum = thread_stratum;
   thread_db_ops.to_has_thread_control = tc_schedlock;
This page took 0.025867 seconds and 4 git commands to generate.