Пример #1
0
static int
attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
{
  struct process_info *proc = current_process ();
  int pid = pid_of (proc);
  ptid_t ptid = ptid_build (pid, ti_p->ti_lid, 0);
  struct lwp_info *lwp;
  int err;

  if (debug_threads)
    debug_printf ("Attaching to thread %ld (LWP %d)\n",
		  (unsigned long) ti_p->ti_tid, ti_p->ti_lid);
  err = linux_attach_lwp (ptid);
  if (err != 0)
    {
      warning ("Could not attach to thread %ld (LWP %d): %s\n",
	       (unsigned long) ti_p->ti_tid, ti_p->ti_lid,
	       linux_ptrace_attach_fail_reason_string (ptid, err));
      return 0;
    }

  lwp = find_lwp_pid (ptid);
  gdb_assert (lwp != NULL);
  lwp->thread_known = 1;
  lwp->th = *th_p;

  return 1;
}
Пример #2
0
static int
maybe_attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p,
		     int *counter)
{
  struct lwp_info *lwp;

  lwp = find_lwp_pid (pid_to_ptid (ti_p->ti_lid));
  if (lwp != NULL)
    return 1;

  if (!attach_thread (th_p, ti_p))
    return 0;

  if (counter != NULL)
    *counter += 1;

  return 1;
}
Пример #3
0
static void
arm_new_fork (struct process_info *parent, struct process_info *child)
{
  struct arch_process_info *parent_proc_info;
  struct arch_process_info *child_proc_info;
  struct lwp_info *child_lwp;
  struct arch_lwp_info *child_lwp_info;
  int i;

  /* These are allocated by linux_add_process.  */
  gdb_assert (parent->priv != NULL
	      && parent->priv->arch_private != NULL);
  gdb_assert (child->priv != NULL
	      && child->priv->arch_private != NULL);

  parent_proc_info = parent->priv->arch_private;
  child_proc_info = child->priv->arch_private;

  /* Linux kernel before 2.6.33 commit
     72f674d203cd230426437cdcf7dd6f681dad8b0d
     will inherit hardware debug registers from parent
     on fork/vfork/clone.  Newer Linux kernels create such tasks with
     zeroed debug registers.

     GDB core assumes the child inherits the watchpoints/hw
     breakpoints of the parent, and will remove them all from the
     forked off process.  Copy the debug registers mirrors into the
     new process so that all breakpoints and watchpoints can be
     removed together.  The debug registers mirror will become zeroed
     in the end before detaching the forked off process, thus making
     this compatible with older Linux kernels too.  */

  *child_proc_info = *parent_proc_info;

  /* Mark all the hardware breakpoints and watchpoints as changed to
     make sure that the registers will be updated.  */
  child_lwp = find_lwp_pid (ptid_of (child));
  child_lwp_info = child_lwp->arch_private;
  for (i = 0; i < MAX_BPTS; i++)
    child_lwp_info->bpts_changed[i] = 1;
  for (i = 0; i < MAX_WPTS; i++)
    child_lwp_info->wpts_changed[i] = 1;
}
Пример #4
0
static int
attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
{
  struct process_info *proc = current_process ();
  int pid = pid_of (proc);
  ptid_t ptid = ptid_build (pid, ti_p->ti_lid, 0);
  struct lwp_info *lwp;
  int err;

  if (debug_threads)
    debug_printf ("Attaching to thread %ld (LWP %d)\n",
		  ti_p->ti_tid, ti_p->ti_lid);
  err = linux_attach_lwp (ptid);
  if (err != 0)
    {
      warning ("Could not attach to thread %ld (LWP %d): %s\n",
	       ti_p->ti_tid, ti_p->ti_lid,
	       linux_ptrace_attach_fail_reason_string (ptid, err));
      return 0;
    }

  lwp = find_lwp_pid (ptid);
  gdb_assert (lwp != NULL);
  lwp->thread_known = 1;
  lwp->th = *th_p;

  if (thread_db_use_events)
    {
      td_err_e err;
      struct thread_db *thread_db = proc->priv->thread_db;

      err = thread_db->td_thr_event_enable_p (th_p, 1);
      if (err != TD_OK)
	error ("Cannot enable thread event reporting for %d: %s",
	       ti_p->ti_lid, thread_db_err_str (err));
    }

  return 1;
}
Пример #5
0
ps_err_e
ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
{
#ifdef HAVE_REGSETS
  struct lwp_info *lwp;
  struct thread_info *reg_inferior, *save_inferior;
  struct regcache *regcache;

  lwp = find_lwp_pid (pid_to_ptid (lwpid));
  if (lwp == NULL)
    return PS_ERR;

  reg_inferior = get_lwp_thread (lwp);
  save_inferior = current_inferior;
  current_inferior = reg_inferior;
  regcache = get_thread_regcache (current_inferior, 1);
  gregset_info ()->fill_function (regcache, gregset);

  current_inferior = save_inferior;
  return PS_OK;
#else
  return PS_ERR;
#endif
}