btrace: split record_btrace_step_thread
[deliverable/binutils-gdb.git] / gdb / linux-thread-db.c
index f09685eb21811a6cbd1a9722f53a14e60811d887..855629bcf466e92ec4c02ea7d85c12a9f52773e5 100644 (file)
@@ -42,9 +42,9 @@
 #include "nat/linux-osdata.h"
 #include "auto-load.h"
 #include "cli/cli-utils.h"
-
 #include <signal.h>
 #include <ctype.h>
+#include "nat/linux-namespaces.h"
 
 /* GNU/Linux libthread_db support.
 
@@ -174,40 +174,19 @@ struct thread_db_info
 
   /* Pointers to the libthread_db functions.  */
 
-  td_err_e (*td_init_p) (void);
-
-  td_err_e (*td_ta_new_p) (struct ps_prochandle * ps,
-                               td_thragent_t **ta);
-  td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
-                                 td_thrhandle_t *__th);
-  td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta,
-                                  lwpid_t lwpid, td_thrhandle_t *th);
-  td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
-                               td_thr_iter_f *callback, void *cbdata_p,
-                               td_thr_state_e state, int ti_pri,
-                               sigset_t *ti_sigmask_p,
-                               unsigned int ti_user_flags);
-  td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
-                                 td_event_e event, td_notify_t *ptr);
-  td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
-                                td_thr_events_t *event);
-  td_err_e (*td_ta_clear_event_p) (const td_thragent_t *ta,
-                                  td_thr_events_t *event);
-  td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
-                                   td_event_msg_t *msg);
-
-  td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
-  td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
-                                td_thrinfo_t *infop);
-  td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th,
-                                    int event);
-
-  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);
+  td_init_ftype *td_init_p;
+  td_ta_new_ftype *td_ta_new_p;
+  td_ta_map_lwp2thr_ftype *td_ta_map_lwp2thr_p;
+  td_ta_thr_iter_ftype *td_ta_thr_iter_p;
+  td_ta_event_addr_ftype *td_ta_event_addr_p;
+  td_ta_set_event_ftype *td_ta_set_event_p;
+  td_ta_clear_event_ftype *td_ta_clear_event_p;
+  td_ta_event_getmsg_ftype * td_ta_event_getmsg_p;
+  td_thr_validate_ftype *td_thr_validate_p;
+  td_thr_get_info_ftype *td_thr_get_info_p;
+  td_thr_event_enable_ftype *td_thr_event_enable_p;
+  td_thr_tls_get_addr_ftype *td_thr_tls_get_addr_p;
+  td_thr_tlsbase_ftype *td_thr_tlsbase_p;
 };
 
 /* List of known processes using thread_db, and the required
@@ -232,9 +211,8 @@ static void record_thread (struct thread_db_info *info,
 static struct thread_db_info *
 add_thread_db_info (void *handle)
 {
-  struct thread_db_info *info;
+  struct thread_db_info *info = XCNEW (struct thread_db_info);
 
-  info = xcalloc (1, sizeof (*info));
   info->pid = ptid_get_pid (inferior_ptid);
   info->handle = handle;
 
@@ -394,7 +372,7 @@ have_threads_callback (struct thread_info *thread, void *args)
   if (ptid_get_pid (thread->ptid) != pid)
     return 0;
 
-  return thread->private != NULL;
+  return thread->priv != NULL;
 }
 
 static int
@@ -479,7 +457,7 @@ verbose_dlsym (void *handle, const char *name)
 }
 
 static td_err_e
-enable_thread_event (int event, CORE_ADDR *bp)
+enable_thread_event (td_event_e event, CORE_ADDR *bp)
 {
   td_notify_t notify;
   td_err_e err;
@@ -611,14 +589,13 @@ enable_thread_event_reporting (void)
 static int
 thread_db_find_new_threads_silently (ptid_t ptid)
 {
-  volatile struct gdb_exception except;
 
-  TRY_CATCH (except, RETURN_MASK_ERROR)
+  TRY
     {
       thread_db_find_new_threads_2 (ptid, 1);
     }
 
-  if (except.reason < 0)
+  CATCH (except, RETURN_MASK_ERROR)
     {
       if (libthread_db_debug)
        exception_fprintf (gdb_stdlog, except,
@@ -648,6 +625,8 @@ thread_db_find_new_threads_silently (ptid_t ptid)
          return 1;
        }
     }
+  END_CATCH
+
   return 0;
 }
 
@@ -679,9 +658,20 @@ try_thread_db_load_1 (struct thread_db_info *info)
   /* Initialize pointers to the dynamic library functions we will use.
      Essential functions first.  */
 
-  info->td_init_p = verbose_dlsym (info->handle, "td_init");
-  if (info->td_init_p == NULL)
-    return 0;
+#define TDB_VERBOSE_DLSYM(info, func)                  \
+  info->func ## _p = (func ## _ftype *) verbose_dlsym (info->handle, #func)
+
+#define TDB_DLSYM(info, func)                  \
+  info->func ## _p = (func ## _ftype *) dlsym (info->handle, #func)
+
+#define CHK(a)                                                         \
+  do                                                                   \
+    {                                                                  \
+      if ((a) == NULL)                                                 \
+       return 0;                                                       \
+  } while (0)
+
+  CHK (TDB_VERBOSE_DLSYM (info, td_init));
 
   err = info->td_init_p ();
   if (err != TD_OK)
@@ -691,9 +681,7 @@ try_thread_db_load_1 (struct thread_db_info *info)
       return 0;
     }
 
-  info->td_ta_new_p = verbose_dlsym (info->handle, "td_ta_new");
-  if (info->td_ta_new_p == NULL)
-    return 0;
+  CHK (TDB_VERBOSE_DLSYM (info, td_ta_new));
 
   /* Initialize the structure that identifies the child process.  */
   info->proc_handle.ptid = inferior_ptid;
@@ -722,35 +710,24 @@ try_thread_db_load_1 (struct thread_db_info *info)
       return 0;
     }
 
-  info->td_ta_map_id2thr_p = verbose_dlsym (info->handle, "td_ta_map_id2thr");
-  if (info->td_ta_map_id2thr_p == NULL)
-    return 0;
-
-  info->td_ta_map_lwp2thr_p = verbose_dlsym (info->handle,
-                                            "td_ta_map_lwp2thr");
-  if (info->td_ta_map_lwp2thr_p == NULL)
-    return 0;
-
-  info->td_ta_thr_iter_p = verbose_dlsym (info->handle, "td_ta_thr_iter");
-  if (info->td_ta_thr_iter_p == NULL)
-    return 0;
-
-  info->td_thr_validate_p = verbose_dlsym (info->handle, "td_thr_validate");
-  if (info->td_thr_validate_p == NULL)
-    return 0;
-
-  info->td_thr_get_info_p = verbose_dlsym (info->handle, "td_thr_get_info");
-  if (info->td_thr_get_info_p == NULL)
-    return 0;
+  /* These are essential.  */
+  CHK (TDB_VERBOSE_DLSYM (info, td_ta_map_lwp2thr));
+  CHK (TDB_VERBOSE_DLSYM (info, td_ta_thr_iter));
+  CHK (TDB_VERBOSE_DLSYM (info, td_thr_validate));
+  CHK (TDB_VERBOSE_DLSYM (info, td_thr_get_info));
 
   /* These are not essential.  */
-  info->td_ta_event_addr_p = dlsym (info->handle, "td_ta_event_addr");
-  info->td_ta_set_event_p = dlsym (info->handle, "td_ta_set_event");
-  info->td_ta_clear_event_p = dlsym (info->handle, "td_ta_clear_event");
-  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");
+  TDB_DLSYM (info, td_ta_event_addr);
+  TDB_DLSYM (info, td_ta_set_event);
+  TDB_DLSYM (info, td_ta_clear_event);
+  TDB_DLSYM (info, td_ta_event_getmsg);
+  TDB_DLSYM (info, td_thr_event_enable);
+  TDB_DLSYM (info, td_thr_tls_get_addr);
+  TDB_DLSYM (info, td_thr_tlsbase);
+
+#undef TDB_VERBOSE_DLSYM
+#undef TDB_DLSYM
+#undef CHK
 
   /* 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,
@@ -1210,20 +1187,12 @@ 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.  */
-      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)
+      if (!linux_ns_same (ptid_get_pid (inferior_ptid), LINUX_NS_PID))
        {
          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);
     }
 }
 
@@ -1241,11 +1210,11 @@ thread_db_inferior_created (struct target_ops *target, int from_tty)
    from libthread_db thread state information.  */
 
 static void
-update_thread_state (struct private_thread_info *private,
+update_thread_state (struct private_thread_info *priv,
                     const td_thrinfo_t *ti_p)
 {
-  private->dying = (ti_p->ti_state == TD_THR_UNKNOWN
-                   || ti_p->ti_state == TD_THR_ZOMBIE);
+  priv->dying = (ti_p->ti_state == TD_THR_UNKNOWN
+                || ti_p->ti_state == TD_THR_ZOMBIE);
 }
 
 /* Attach to a new thread.  This function is called when we receive a
@@ -1272,16 +1241,16 @@ attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
   tp = find_thread_ptid (ptid);
   if (tp != NULL)
     {
-      /* If tp->private is NULL, then GDB is already attached to this
+      /* If tp->priv is NULL, then GDB is already attached to this
         thread, but we do not know anything about it.  We can learn
         about it here.  This can only happen if we have some other
         way besides libthread_db to notice new threads (i.e.
         PTRACE_EVENT_CLONE); assume the same mechanism notices thread
         exit, so this can not be a stale thread recreated with the
         same ID.  */
-      if (tp->private != NULL)
+      if (tp->priv != NULL)
        {
-         if (!tp->private->dying)
+         if (!tp->priv->dying)
            return 0;
 
          delete_thread (ptid);
@@ -1328,7 +1297,7 @@ record_thread (struct thread_db_info *info,
               const td_thrinfo_t *ti_p)
 {
   td_err_e err;
-  struct private_thread_info *private;
+  struct private_thread_info *priv;
   int new_thread = (tp == NULL);
 
   /* A thread ID of zero may mean the thread library has not
@@ -1338,18 +1307,19 @@ record_thread (struct thread_db_info *info,
     return;
 
   /* Construct the thread's private data.  */
-  private = xmalloc (sizeof (struct private_thread_info));
-  memset (private, 0, sizeof (struct private_thread_info));
+  priv = XCNEW (struct private_thread_info);
 
-  private->th = *th_p;
-  private->tid = ti_p->ti_tid;
-  update_thread_state (private, ti_p);
+  priv->th = *th_p;
+  priv->tid = ti_p->ti_tid;
+  update_thread_state (priv, ti_p);
 
-  /* Add the thread to GDB's thread list.  */
-  if (tp == NULL)
-    tp = add_thread_with_info (ptid, private);
+  /* Add the thread to GDB's thread list.  If we already know about a
+     thread with this PTID, but it's marked exited, then the kernel
+     reused the tid of an old thread.  */
+  if (tp == NULL || tp->state == THREAD_EXITED)
+    tp = add_thread_with_info (ptid, priv);
   else
-    tp->private = private;
+    tp->priv = priv;
 
   /* Enable thread event reporting for this thread, except when
      debugging a core file.  */
@@ -1379,8 +1349,8 @@ detach_thread (ptid_t ptid)
      something re-uses its thread ID.  We'll report the thread exit
      when the underlying LWP dies.  */
   thread_info = find_thread_ptid (ptid);
-  gdb_assert (thread_info != NULL && thread_info->private != NULL);
-  thread_info->private->dying = 1;
+  gdb_assert (thread_info != NULL && thread_info->priv != NULL);
+  thread_info->priv->dying = 1;
 }
 
 static void
@@ -1437,8 +1407,10 @@ check_event (ptid_t ptid)
   info = get_thread_db_info (ptid_get_pid (ptid));
 
   /* Bail out early if we're not at a thread event breakpoint.  */
-  stop_pc = regcache_read_pc (regcache)
-           - target_decr_pc_after_break (gdbarch);
+  stop_pc = regcache_read_pc (regcache);
+  if (!target_supports_stopped_by_sw_breakpoint ())
+    stop_pc -= gdbarch_decr_pc_after_break (gdbarch);
+
   if (stop_pc != info->td_create_bp_addr
       && stop_pc != info->td_death_bp_addr)
     return;
@@ -1649,7 +1621,7 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
 
   ptid = ptid_build (info->pid, ti.ti_lid, 0);
   tp = find_thread_ptid (ptid);
-  if (tp == NULL || tp->private == NULL)
+  if (tp == NULL || tp->priv == NULL)
     {
       if (attach_thread (ptid, th_p, &ti))
        cb_data->new_threads += 1;
@@ -1666,7 +1638,7 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
     {
       /* Need to update this if not using the libthread_db events
         (particularly, the TD_DEATH event).  */
-      update_thread_state (tp->private, &ti);
+      update_thread_state (tp->priv, &ti);
     }
 
   return 0;
@@ -1679,7 +1651,6 @@ static int
 find_new_threads_once (struct thread_db_info *info, int iteration,
                       td_err_e *errp)
 {
-  volatile struct gdb_exception except;
   struct callback_data data;
   td_err_e err = TD_ERR;
 
@@ -1689,7 +1660,7 @@ find_new_threads_once (struct thread_db_info *info, int iteration,
   /* See comment in thread_db_update_thread_list.  */
   gdb_assert (!target_has_execution || thread_db_use_events ());
 
-  TRY_CATCH (except, RETURN_MASK_ERROR)
+  TRY
     {
       /* Iterate over all user-space threads to discover new threads.  */
       err = info->td_ta_thr_iter_p (info->thread_agent,
@@ -1700,13 +1671,18 @@ find_new_threads_once (struct thread_db_info *info, int iteration,
                                    TD_SIGNO_MASK,
                                    TD_THR_ANY_USER_FLAGS);
     }
+  CATCH (except, RETURN_MASK_ERROR)
+    {
+      if (libthread_db_debug)
+       {
+         exception_fprintf (gdb_stdlog, except,
+                            "Warning: find_new_threads_once: ");
+       }
+    }
+  END_CATCH
 
   if (libthread_db_debug)
     {
-      if (except.reason < 0)
-       exception_fprintf (gdb_stdlog, except,
-                          "Warning: find_new_threads_once: ");
-
       fprintf_unfiltered (gdb_stdlog,
                          _("Found %d new threads in iteration %d.\n"),
                          data.new_threads, iteration);
@@ -1829,12 +1805,12 @@ thread_db_pid_to_str (struct target_ops *ops, ptid_t ptid)
   struct thread_info *thread_info = find_thread_ptid (ptid);
   struct target_ops *beneath;
 
-  if (thread_info != NULL && thread_info->private != NULL)
+  if (thread_info != NULL && thread_info->priv != NULL)
     {
       static char buf[64];
       thread_t tid;
 
-      tid = thread_info->private->tid;
+      tid = thread_info->priv->tid;
       snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)",
                tid, ptid_get_lwp (ptid));
 
@@ -1852,10 +1828,10 @@ static char *
 thread_db_extra_thread_info (struct target_ops *self,
                             struct thread_info *info)
 {
-  if (info->private == NULL)
+  if (info->priv == NULL)
     return NULL;
 
-  if (info->private->dying)
+  if (info->priv->dying)
     return "Exiting";
 
   return NULL;
@@ -1873,14 +1849,17 @@ thread_db_get_thread_local_address (struct target_ops *ops,
   struct thread_info *thread_info;
   struct target_ops *beneath;
 
-  /* If we have not discovered any threads yet, check now.  */
-  if (!have_threads (ptid))
-    thread_db_find_new_threads_1 (ptid);
-
   /* Find the matching thread.  */
   thread_info = find_thread_ptid (ptid);
 
-  if (thread_info != NULL && thread_info->private != NULL)
+  /* We may not have discovered the thread yet.  */
+  if (thread_info != NULL && thread_info->priv == NULL)
+    {
+      thread_from_lwp (ptid);
+      thread_info = find_thread_ptid (ptid);
+    }
+
+  if (thread_info != NULL && thread_info->priv != NULL)
     {
       td_err_e err;
       psaddr_t address;
@@ -1899,7 +1878,7 @@ thread_db_get_thread_local_address (struct target_ops *ops,
          /* 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,
+         err = info->td_thr_tls_get_addr_p (&thread_info->priv->th,
                                             (psaddr_t)(uintptr_t) lm,
                                             offset, &address);
        }
@@ -1917,7 +1896,7 @@ thread_db_get_thread_local_address (struct target_ops *ops,
             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,
+         err = info->td_thr_tlsbase_p (&thread_info->priv->th,
                                        1, &address);
          address = (char *) address + offset;
        }
@@ -2020,7 +1999,7 @@ info_auto_load_libthread_db (char *args, int from_tty)
     if (info->filename != NULL)
       info_count++;
 
-  array = xmalloc (sizeof (*array) * info_count);
+  array = XNEWVEC (struct thread_db_info *, info_count);
   back_to = make_cleanup (xfree, array);
 
   info_count = 0;
This page took 0.035259 seconds and 4 git commands to generate.