static void aarch64_linux_prepare_to_resume (struct lwp_info *lwp) { struct thread_info *thread = get_lwp_thread (lwp); ptid_t ptid = ptid_of (thread); struct arch_lwp_info *info = lwp->arch_private; if (DR_HAS_CHANGED (info->dr_changed_bp) || DR_HAS_CHANGED (info->dr_changed_wp)) { int tid = ptid_get_lwp (ptid); struct process_info *proc = find_process_pid (ptid_get_pid (ptid)); struct aarch64_debug_reg_state *state = &proc->priv->arch_private->debug_reg_state; if (show_debug_regs) fprintf (stderr, "prepare_to_resume thread %ld\n", lwpid_of (thread)); /* Watchpoints. */ if (DR_HAS_CHANGED (info->dr_changed_wp)) { aarch64_linux_set_debug_regs (state, tid, 1); DR_CLEAR_CHANGED (info->dr_changed_wp); } /* Breakpoints. */ if (DR_HAS_CHANGED (info->dr_changed_bp)) { aarch64_linux_set_debug_regs (state, tid, 0); DR_CLEAR_CHANGED (info->dr_changed_bp); } } }
void remove_thread (struct thread_info *thread) { if (thread->btrace != NULL) target_disable_btrace (thread->btrace); discard_queued_stop_replies (ptid_of (thread)); remove_inferior (&all_threads, (struct inferior_list_entry *) thread); free_one_thread (&thread->entry); }
void remove_thread (struct thread_info *thread) { if (thread->btrace != NULL) target_disable_btrace (thread->btrace); discard_queued_stop_replies (ptid_of (thread)); all_threads.remove (thread); free_one_thread (thread); if (current_thread == thread) current_thread = NULL; }
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; }
int prepare_to_access_memory (void) { struct thread_search search; struct thread_info *thread; memset (&search, 0, sizeof (search)); search.current_gen_ptid = general_thread; prev_general_thread = general_thread; if (the_target->prepare_to_access_memory != NULL) { int res; res = the_target->prepare_to_access_memory (); if (res != 0) return res; } find_inferior (&all_threads, thread_search_callback, &search); /* Prefer a stopped thread. If none is found, try the current thread. Otherwise, take the first thread in the process. If none is found, undo the effects of target->prepare_to_access_memory() and return error. */ if (search.stopped != NULL) thread = search.stopped; else if (search.current != NULL) thread = search.current; else if (search.first != NULL) thread = search.first; else { done_accessing_memory (); return 1; } current_thread = thread; general_thread = ptid_of (thread); return 0; }
static int thread_search_callback (struct inferior_list_entry *entry, void *args) { struct thread_info *thread = (struct thread_info *) entry; struct thread_search *s = (struct thread_search *) args; if (ptid_get_pid (entry->id) == ptid_get_pid (s->current_gen_ptid) && mythread_alive (ptid_of (thread))) { if (s->stopped == NULL && the_target->thread_stopped != NULL && thread_stopped (thread)) s->stopped = thread; if (s->first == NULL) s->first = thread; if (s->current == NULL && ptid_equal (s->current_gen_ptid, entry->id)) s->current = thread; } return 0; }