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; }
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; }
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; }
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; }
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 }