]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/linux-thread-db.c
[binutils, ARM, 4/16] BF insns infrastructure with array of relocs in struct arm_it
[thirdparty/binutils-gdb.git] / gdb / linux-thread-db.c
index b67bd5d00dca56e05202b1232e216f12782c0935..a67f9b95145a1667cbbda459aa125022bf12a14d 100644 (file)
@@ -1,6 +1,6 @@
 /* libthread_db assisted debugging support, generic parts.
 
-   Copyright (C) 1999-2018 Free Software Foundation, Inc.
+   Copyright (C) 1999-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -21,7 +21,7 @@
 #include <dlfcn.h>
 #include "gdb_proc_service.h"
 #include "nat/gdb_thread_db.h"
-#include "gdb_vecs.h"
+#include "common/gdb_vecs.h"
 #include "bfd.h"
 #include "command.h"
 #include "gdbcmd.h"
@@ -85,17 +85,17 @@ static const target_info thread_db_target_info = {
 class thread_db_target final : public target_ops
 {
 public:
-  thread_db_target ();
-
   const target_info &info () const override
   { return thread_db_target_info; }
 
+  strata stratum () const override { return thread_stratum; }
+
   void detach (inferior *, int) override;
   ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
   void resume (ptid_t, int, enum gdb_signal) override;
   void mourn_inferior () override;
   void update_thread_list () override;
-  const char *pid_to_str (ptid_t) override;
+  std::string pid_to_str (ptid_t) override;
   CORE_ADDR get_thread_local_address (ptid_t ptid,
                                      CORE_ADDR load_module_addr,
                                      CORE_ADDR offset) override;
@@ -105,13 +105,9 @@ public:
   thread_info *thread_handle_to_thread_info (const gdb_byte *thread_handle,
                                             int handle_len,
                                             inferior *inf) override;
+  gdb::byte_vector thread_info_to_thread_handle (struct thread_info *) override;
 };
 
-thread_db_target::thread_db_target ()
-{
-  this->to_stratum = thread_stratum;
-}
-
 static char *libthread_db_search_path;
 
 /* Set to non-zero if thread_db auto-loading is enabled
@@ -199,6 +195,7 @@ struct thread_db_info
 
   td_init_ftype *td_init_p;
   td_ta_new_ftype *td_ta_new_p;
+  td_ta_delete_ftype *td_ta_delete_p;
   td_ta_map_lwp2thr_ftype *td_ta_map_lwp2thr_p;
   td_ta_thr_iter_ftype *td_ta_thr_iter_p;
   td_thr_get_info_ftype *td_thr_get_info_p;
@@ -230,7 +227,7 @@ add_thread_db_info (void *handle)
 {
   struct thread_db_info *info = XCNEW (struct thread_db_info);
 
-  info->pid = ptid_get_pid (inferior_ptid);
+  info->pid = inferior_ptid.pid ();
   info->handle = handle;
 
   /* The workaround works by reading from /proc/pid/status, so it is
@@ -259,6 +256,8 @@ get_thread_db_info (int pid)
   return NULL;
 }
 
+static const char *thread_db_err_str (td_err_e err);
+
 /* When PID has exited or has been detached, we no longer want to keep
    track of it as using libpthread.  Call this function to discard
    thread_db related info related to PID.  Note that this closes
@@ -278,6 +277,16 @@ delete_thread_db_info (int pid)
   if (info == NULL)
     return;
 
+  if (info->thread_agent != NULL && info->td_ta_delete_p != NULL)
+    {
+      td_err_e err = info->td_ta_delete_p (info->thread_agent);
+
+      if (err != TD_OK)
+       warning (_("Cannot deregister process %d from libthread_db: %s"),
+                pid, thread_db_err_str (err));
+      info->thread_agent = NULL;
+    }
+
   if (info->handle != NULL)
     dlclose (info->handle);
 
@@ -394,17 +403,17 @@ thread_from_lwp (thread_info *stopped, ptid_t ptid)
 
   /* This ptid comes from linux-nat.c, which should always fill in the
      LWP.  */
-  gdb_assert (ptid_get_lwp (ptid) != 0);
+  gdb_assert (ptid.lwp () != 0);
 
-  info = get_thread_db_info (ptid_get_pid (ptid));
+  info = get_thread_db_info (ptid.pid ());
 
   /* Access an lwp we know is stopped.  */
   info->proc_handle.thread = stopped;
-  err = info->td_ta_map_lwp2thr_p (info->thread_agent, ptid_get_lwp (ptid),
+  err = info->td_ta_map_lwp2thr_p (info->thread_agent, ptid.lwp (),
                                   &th);
   if (err != TD_OK)
     error (_("Cannot find user-level thread for LWP %ld: %s"),
-          ptid_get_lwp (ptid), thread_db_err_str (err));
+          ptid.lwp (), thread_db_err_str (err));
 
   err = info->td_thr_get_info_p (&th, &ti);
   if (err != TD_OK)
@@ -424,7 +433,7 @@ thread_db_notice_clone (ptid_t parent, ptid_t child)
 {
   struct thread_db_info *info;
 
-  info = get_thread_db_info (ptid_get_pid (child));
+  info = get_thread_db_info (child.pid ());
 
   if (info == NULL)
     return 0;
@@ -489,12 +498,12 @@ static int
 thread_db_find_new_threads_silently (thread_info *stopped)
 {
 
-  TRY
+  try
     {
       thread_db_find_new_threads_2 (stopped, true);
     }
 
-  CATCH (except, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &except)
     {
       if (libthread_db_debug)
        exception_fprintf (gdb_stdlog, except,
@@ -524,7 +533,6 @@ thread_db_find_new_threads_silently (thread_info *stopped)
          return 1;
        }
     }
-  END_CATCH
 
   return 0;
 }
@@ -749,7 +757,7 @@ check_thread_db (struct thread_db_info *info, bool log_progress)
      fail.  */
   linux_stop_and_wait_all_lwps ();
 
-  TRY
+  try
     {
       td_err_e err = td_ta_thr_iter_p (info->thread_agent,
                                       check_thread_db_callback,
@@ -765,7 +773,7 @@ check_thread_db (struct thread_db_info *info, bool log_progress)
       if (!tdb_testinfo->threads_seen)
        error (_("no threads seen"));
     }
-  CATCH (except, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &except)
     {
       if (warning_pre_print)
        fputs_unfiltered (warning_pre_print, gdb_stderr);
@@ -775,7 +783,6 @@ check_thread_db (struct thread_db_info *info, bool log_progress)
 
       test_passed = false;
     }
-  END_CATCH
 
   if (test_passed && log_progress)
     debug_printf (_("libthread_db integrity checks passed.\n"));
@@ -860,6 +867,7 @@ try_thread_db_load_1 (struct thread_db_info *info)
   /* These are not essential.  */
   TDB_DLSYM (info, td_thr_tls_get_addr);
   TDB_DLSYM (info, td_thr_tlsbase);
+  TDB_DLSYM (info, td_ta_delete);
 
   /* It's best to avoid td_ta_thr_iter if possible.  That walks data
      structures in the inferior's address space that may be corrupted,
@@ -871,7 +879,7 @@ try_thread_db_load_1 (struct thread_db_info *info)
      td_ta_map_lwp2thr uses ps_get_thread_area, but we can't use that
      currently on core targets, as it uses ptrace directly.  */
   if (target_has_execution
-      && linux_proc_task_list_dir_exists (ptid_get_pid (inferior_ptid)))
+      && linux_proc_task_list_dir_exists (inferior_ptid.pid ()))
     info->td_ta_thr_iter_p = NULL;
   else
     CHK (TDB_VERBOSE_DLSYM (info, td_ta_thr_iter));
@@ -890,13 +898,13 @@ try_thread_db_load_1 (struct thread_db_info *info)
   if (info->td_ta_thr_iter_p == NULL)
     {
       struct lwp_info *lp;
-      int pid = ptid_get_pid (inferior_ptid);
+      int pid = inferior_ptid.pid ();
       thread_info *curr_thread = inferior_thread ();
 
       linux_stop_and_wait_all_lwps ();
 
       ALL_LWPS (lp)
-       if (ptid_get_pid (lp->ptid) == pid)
+       if (lp->ptid.pid () == pid)
          thread_from_lwp (curr_thread, lp->ptid);
 
       linux_unstop_all_lwps ();
@@ -1003,7 +1011,7 @@ try_thread_db_load (const char *library, int check_auto_load_safe)
     return 1;
 
   /* This library "refused" to work on current inferior.  */
-  delete_thread_db_info (ptid_get_pid (inferior_ptid));
+  delete_thread_db_info (inferior_ptid.pid ());
   return 0;
 }
 
@@ -1044,12 +1052,10 @@ try_thread_db_load_from_pdir_1 (struct objfile *obj, const char *subdir)
 static int
 try_thread_db_load_from_pdir (const char *subdir)
 {
-  struct objfile *obj;
-
   if (!auto_load_thread_db)
     return 0;
 
-  ALL_OBJFILES (obj)
+  for (objfile *obj : current_program_space->objfiles ())
     if (libpthread_name_p (objfile_name (obj)))
       {
        if (try_thread_db_load_from_pdir_1 (obj, subdir))
@@ -1158,9 +1164,7 @@ thread_db_load_search (void)
 static int
 has_libpthread (void)
 {
-  struct objfile *obj;
-
-  ALL_OBJFILES (obj)
+  for (objfile *obj : current_program_space->objfiles ())
     if (libpthread_name_p (objfile_name (obj)))
       return 1;
 
@@ -1175,7 +1179,7 @@ thread_db_load (void)
 {
   struct thread_db_info *info;
 
-  info = get_thread_db_info (ptid_get_pid (inferior_ptid));
+  info = get_thread_db_info (inferior_ptid.pid ());
 
   if (info != NULL)
     return 1;
@@ -1284,7 +1288,7 @@ check_pid_namespace_match (void)
         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.  */
-      if (!linux_ns_same (ptid_get_pid (inferior_ptid), LINUX_NS_PID))
+      if (!linux_ns_same (inferior_ptid.pid (), LINUX_NS_PID))
        {
          warning (_ ("Target and debugger are in different PID "
                      "namespaces; thread lists and other data are "
@@ -1384,7 +1388,7 @@ thread_db_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
       return ptid;
     }
 
-  info = get_thread_db_info (ptid_get_pid (ptid));
+  info = get_thread_db_info (ptid.pid ());
 
   /* If this process isn't using thread_db, we're done.  */
   if (info == NULL)
@@ -1394,7 +1398,7 @@ thread_db_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
     {
       /* New image, it may or may not end up using thread_db.  Assume
         not unless we find otherwise.  */
-      delete_thread_db_info (ptid_get_pid (ptid));
+      delete_thread_db_info (ptid.pid ());
       if (!thread_db_list)
        unpush_target (&the_thread_db_target);
 
@@ -1410,7 +1414,7 @@ thread_db_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
 void
 thread_db_target::mourn_inferior ()
 {
-  delete_thread_db_info (ptid_get_pid (inferior_ptid));
+  delete_thread_db_info (inferior_ptid.pid ());
 
   beneath ()->mourn_inferior ();
 
@@ -1504,7 +1508,7 @@ find_new_threads_once (struct thread_db_info *info, int iteration,
   /* See comment in thread_db_update_thread_list.  */
   gdb_assert (info->td_ta_thr_iter_p != NULL);
 
-  TRY
+  try
     {
       /* Iterate over all user-space threads to discover new threads.  */
       err = info->td_ta_thr_iter_p (info->thread_agent,
@@ -1515,7 +1519,7 @@ find_new_threads_once (struct thread_db_info *info, int iteration,
                                    TD_SIGNO_MASK,
                                    TD_THR_ANY_USER_FLAGS);
     }
-  CATCH (except, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &except)
     {
       if (libthread_db_debug)
        {
@@ -1523,7 +1527,6 @@ find_new_threads_once (struct thread_db_info *info, int iteration,
                             "Warning: find_new_threads_once: ");
        }
     }
-  END_CATCH
 
   if (libthread_db_debug)
     {
@@ -1587,11 +1590,10 @@ void
 thread_db_target::update_thread_list ()
 {
   struct thread_db_info *info;
-  struct inferior *inf;
 
   prune_threads ();
 
-  ALL_INFERIORS (inf)
+  for (inferior *inf : all_inferiors ())
     {
       struct thread_info *thread;
 
@@ -1627,20 +1629,17 @@ thread_db_target::update_thread_list ()
   this->beneath ()->update_thread_list ();
 }
 
-const char *
+std::string
 thread_db_target::pid_to_str (ptid_t ptid)
 {
   struct thread_info *thread_info = find_thread_ptid (ptid);
 
   if (thread_info != NULL && thread_info->priv != NULL)
     {
-      static char buf[64];
       thread_db_thread_info *priv = get_thread_db_thread_info (thread_info);
 
-      snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)",
-               (unsigned long) priv->tid, ptid_get_lwp (ptid));
-
-      return buf;
+      return string_printf ("Thread 0x%lx (LWP %ld)",
+                           (unsigned long) priv->tid, ptid.lwp ());
     }
 
   return beneath ()->pid_to_str (ptid);
@@ -1671,7 +1670,6 @@ thread_db_target::thread_handle_to_thread_info (const gdb_byte *thread_handle,
                                                int handle_len,
                                                inferior *inf)
 {
-  struct thread_info *tp;
   thread_t handle_tid;
 
   /* Thread handle sizes must match in order to proceed.  We don't use an
@@ -1684,17 +1682,35 @@ thread_db_target::thread_handle_to_thread_info (const gdb_byte *thread_handle,
 
   handle_tid = * (const thread_t *) thread_handle;
 
-  ALL_NON_EXITED_THREADS (tp)
+  for (thread_info *tp : inf->non_exited_threads ())
     {
       thread_db_thread_info *priv = get_thread_db_thread_info (tp);
 
-      if (tp->inf == inf && priv != NULL && handle_tid == priv->tid)
+      if (priv != NULL && handle_tid == priv->tid)
         return tp;
     }
 
   return NULL;
 }
 
+/* Return the thread handle associated the thread_info pointer TP.  */
+
+gdb::byte_vector
+thread_db_target::thread_info_to_thread_handle (struct thread_info *tp)
+{
+  thread_db_thread_info *priv = get_thread_db_thread_info (tp);
+
+  if (priv == NULL)
+    return gdb::byte_vector ();
+
+  int handle_size = sizeof (priv->tid);
+  gdb::byte_vector rv (handle_size);
+
+  memcpy (rv.data (), &priv->tid, handle_size);
+
+  return rv;
+}
+
 /* Get the address of the thread local variable in load module LM which
    is stored at OFFSET within the thread local storage for thread PTID.  */
 
@@ -1716,7 +1732,7 @@ thread_db_target::get_thread_local_address (ptid_t ptid,
     {
       td_err_e err;
       psaddr_t address;
-      thread_db_info *info = get_thread_db_info (ptid_get_pid (ptid));
+      thread_db_info *info = get_thread_db_info (ptid.pid ());
       thread_db_thread_info *priv = get_thread_db_thread_info (thread_info);
 
       /* Finally, get the address of the variable.  */
@@ -1784,7 +1800,7 @@ ptid_t
 thread_db_target::get_ada_task_ptid (long lwp, long thread)
 {
   /* NPTL uses a 1:1 model, so the LWP id suffices.  */
-  return ptid_t (ptid_get_pid (inferior_ptid), lwp, 0);
+  return ptid_t (inferior_ptid.pid (), lwp, 0);
 }
 
 void
@@ -1792,10 +1808,10 @@ thread_db_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
 {
   struct thread_db_info *info;
 
-  if (ptid_equal (ptid, minus_one_ptid))
-    info = get_thread_db_info (ptid_get_pid (inferior_ptid));
+  if (ptid == minus_one_ptid)
+    info = get_thread_db_info (inferior_ptid.pid ());
   else
-    info = get_thread_db_info (ptid_get_pid (ptid));
+    info = get_thread_db_info (ptid.pid ());
 
   /* This workaround is only needed for child fork lwps stopped in a
      PTRACE_O_TRACEFORK event.  When the inferior is resumed, the
@@ -1923,7 +1939,7 @@ info_auto_load_libthread_db (const char *args, int from_tty)
 static void
 maintenance_check_libthread_db (const char *args, int from_tty)
 {
-  int inferior_pid = ptid_get_pid (inferior_ptid);
+  int inferior_pid = inferior_ptid.pid ();
   struct thread_db_info *info;
 
   if (inferior_pid == 0)
@@ -1976,7 +1992,7 @@ Show whether auto-loading inferior specific libthread_db is enabled."), _("\
 If enabled, libthread_db will be searched in 'set libthread-db-search-path'\n\
 locations to load libthread_db compatible with the inferior.\n\
 Standard system libthread_db still gets loaded even with this option off.\n\
-This options has security implications for untrusted inferiors."),
+This option has security implications for untrusted inferiors."),
                           NULL, show_auto_load_thread_db,
                           auto_load_set_cmdlist_get (),
                           auto_load_show_cmdlist_get ());