X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=gdb%2Fgdbserver%2Flinux-low.c;h=b4c716c72d081e95bfe4444cee99866dc6b86716;hb=fcb056a58dd38cfe7bcd34b7889138bf807c40b8;hp=3d7cfe31b5a7c929c3a1bc68baff2d661e77ba9b;hpb=9a6c7d9c021cfeb290d76584db7a01e57e7c3d4e;p=thirdparty%2Fbinutils-gdb.git diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 3d7cfe31b5a..b4c716c72d0 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -279,7 +279,7 @@ static void enqueue_pending_signal (struct lwp_info *lwp, int signal, siginfo_t static void complete_ongoing_step_over (void); static int linux_low_ptrace_options (int attached); static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp); -static int proceed_one_lwp (struct inferior_list_entry *entry, void *except); +static int proceed_one_lwp (thread_info *thread, void *except); /* When the event-loop is doing a step-over, this points at the thread being stepped. */ @@ -414,7 +414,12 @@ delete_lwp (struct lwp_info *lwp) debug_printf ("deleting %ld\n", lwpid_of (thr)); remove_thread (thr); - free (lwp->arch_private); + + if (the_low_target.delete_thread != NULL) + the_low_target.delete_thread (lwp->arch_private); + else + gdb_assert (lwp->arch_private == NULL); + free (lwp); } @@ -570,7 +575,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat) clone_all_breakpoints (child_thr, event_thr); - tdesc = XNEW (struct target_desc); + tdesc = allocate_target_description (); copy_target_description (tdesc, parent_proc->tdesc); child_proc->tdesc = tdesc; @@ -656,6 +661,8 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat) new_lwp->status_pending = status; } + thread_db_notice_clone (event_thr, ptid); + /* Don't report the event. */ return 1; } @@ -676,7 +683,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat) else if (event == PTRACE_EVENT_EXEC && report_exec_events) { struct process_info *proc; - VEC (int) *syscalls_to_catch; + std::vector syscalls_to_catch; ptid_t event_ptid; pid_t event_pid; @@ -692,8 +699,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat) /* Save the syscall list from the execing process. */ proc = get_thread_process (event_thr); - syscalls_to_catch = proc->syscalls_to_catch; - proc->syscalls_to_catch = NULL; + syscalls_to_catch = std::move (proc->syscalls_to_catch); /* Delete the execing process and all its threads. */ linux_mourn (proc); @@ -724,7 +730,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat) /* Restore the list to catch. Don't rely on the client, which is free to avoid sending a new list when the architecture doesn't change. Also, for ANY_SYSCALL, the architecture doesn't really matter. */ - proc->syscalls_to_catch = syscalls_to_catch; + proc->syscalls_to_catch = std::move (syscalls_to_catch); /* Report the event. */ *orig_event_lwp = event_lwp; @@ -1241,11 +1247,11 @@ struct counter }; static int -second_thread_of_pid_p (struct inferior_list_entry *entry, void *args) +second_thread_of_pid_p (thread_info *thread, void *args) { struct counter *counter = (struct counter *) args; - if (ptid_get_pid (entry->id) == counter->pid) + if (thread->id.pid () == counter->pid) { if (++counter->count > 1) return 1; @@ -1354,13 +1360,12 @@ kill_wait_lwp (struct lwp_info *lwp) except the leader. */ static int -kill_one_lwp_callback (struct inferior_list_entry *entry, void *args) +kill_one_lwp_callback (thread_info *thread, void *args) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lwp = get_thread_lwp (thread); int pid = * (int *) args; - if (ptid_get_pid (entry->id) != pid) + if (thread->id.pid () != pid) return 0; /* We avoid killing the first thread here, because of a Linux kernel (at @@ -1372,7 +1377,7 @@ kill_one_lwp_callback (struct inferior_list_entry *entry, void *args) { if (debug_threads) debug_printf ("lkop: is last of process %s\n", - target_pid_to_str (entry->id)); + target_pid_to_str (thread->id)); return 0; } @@ -1587,21 +1592,20 @@ linux_detach_one_lwp (struct lwp_info *lwp) given process. */ static int -linux_detach_lwp_callback (struct inferior_list_entry *entry, void *args) +linux_detach_lwp_callback (thread_info *thread, void *args) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lwp = get_thread_lwp (thread); int pid = *(int *) args; int lwpid = lwpid_of (thread); /* Skip other processes. */ - if (ptid_get_pid (entry->id) != pid) + if (thread->id.pid () != pid) return 0; /* We don't actually detach from the thread group leader just yet. If the thread group exits, we must reap the zombie clone lwps before we're able to reap the leader. */ - if (ptid_get_pid (entry->id) == lwpid) + if (thread->id.pid () == lwpid) return 0; linux_detach_one_lwp (lwp); @@ -1655,9 +1659,8 @@ linux_detach (int pid) /* Remove all LWPs that belong to process PROC from the lwp list. */ static int -delete_lwp_callback (struct inferior_list_entry *entry, void *proc) +delete_lwp_callback (thread_info *thread, void *proc) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lwp = get_thread_lwp (thread); struct process_info *process = (struct process_info *) proc; @@ -1680,7 +1683,10 @@ linux_mourn (struct process_info *process) /* Freeing all private data. */ priv = process->priv; - free (priv->arch_private); + if (the_low_target.delete_process != NULL) + the_low_target.delete_process (priv->arch_private); + else + gdb_assert (priv->arch_private == NULL); free (priv); process->priv = NULL; @@ -1804,9 +1810,8 @@ lwp_resumed (struct lwp_info *lwp) /* Return 1 if this lwp has an interesting status pending. */ static int -status_pending_p_callback (struct inferior_list_entry *entry, void *arg) +status_pending_p_callback (thread_info *thread, void *arg) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lp = get_thread_lwp (thread); ptid_t ptid = * (ptid_t *) arg; @@ -1829,7 +1834,7 @@ status_pending_p_callback (struct inferior_list_entry *entry, void *arg) } static int -same_lwp (struct inferior_list_entry *entry, void *data) +same_lwp (thread_info *thread, void *data) { ptid_t ptid = *(ptid_t *) data; int lwp; @@ -1839,7 +1844,7 @@ same_lwp (struct inferior_list_entry *entry, void *data) else lwp = ptid_get_pid (ptid); - if (ptid_get_lwp (entry->id) == lwp) + if (thread->id.lwp () == lwp) return 1; return 0; @@ -1848,13 +1853,12 @@ same_lwp (struct inferior_list_entry *entry, void *data) struct lwp_info * find_lwp_pid (ptid_t ptid) { - struct inferior_list_entry *thread - = find_inferior (&all_threads, same_lwp, &ptid); + thread_info *thread = find_inferior (&all_threads, same_lwp, &ptid); if (thread == NULL) return NULL; - return get_thread_lwp ((struct thread_info *) thread); + return get_thread_lwp (thread); } /* Return the number of known LWPs in the tgid given by PID. */ @@ -1862,55 +1866,16 @@ find_lwp_pid (ptid_t ptid) static int num_lwps (int pid) { - struct inferior_list_entry *inf, *tmp; int count = 0; - ALL_INFERIORS (&all_threads, inf, tmp) + for_each_thread (pid, [&] (thread_info *thread) { - if (ptid_get_pid (inf->id) == pid) - count++; - } + count++; + }); return count; } -/* The arguments passed to iterate_over_lwps. */ - -struct iterate_over_lwps_args -{ - /* The FILTER argument passed to iterate_over_lwps. */ - ptid_t filter; - - /* The CALLBACK argument passed to iterate_over_lwps. */ - iterate_over_lwps_ftype *callback; - - /* The DATA argument passed to iterate_over_lwps. */ - void *data; -}; - -/* Callback for find_inferior used by iterate_over_lwps to filter - calls to the callback supplied to that function. Returning a - nonzero value causes find_inferiors to stop iterating and return - the current inferior_list_entry. Returning zero indicates that - find_inferiors should continue iterating. */ - -static int -iterate_over_lwps_filter (struct inferior_list_entry *entry, void *args_p) -{ - struct iterate_over_lwps_args *args - = (struct iterate_over_lwps_args *) args_p; - - if (ptid_match (entry->id, args->filter)) - { - struct thread_info *thr = (struct thread_info *) entry; - struct lwp_info *lwp = get_thread_lwp (thr); - - return (*args->callback) (lwp, args->data); - } - - return 0; -} - /* See nat/linux-nat.h. */ struct lwp_info * @@ -1918,14 +1883,17 @@ iterate_over_lwps (ptid_t filter, iterate_over_lwps_ftype callback, void *data) { - struct iterate_over_lwps_args args = {filter, callback, data}; - struct inferior_list_entry *entry; + thread_info *thread = find_thread (filter, [&] (thread_info *thread) + { + lwp_info *lwp = get_thread_lwp (thread); + + return callback (lwp, data); + }); - entry = find_inferior (&all_threads, iterate_over_lwps_filter, &args); - if (entry == NULL) + if (thread == NULL) return NULL; - return get_thread_lwp ((struct thread_info *) entry); + return get_thread_lwp (thread); } /* Detect zombie thread group leaders, and "exit" them. We can't reap @@ -1934,79 +1902,75 @@ iterate_over_lwps (ptid_t filter, static void check_zombie_leaders (void) { - struct process_info *proc, *tmp; + for_each_process ([] (process_info *proc) { + pid_t leader_pid = pid_of (proc); + struct lwp_info *leader_lp; - ALL_PROCESSES (proc, tmp) - { - pid_t leader_pid = pid_of (proc); - struct lwp_info *leader_lp; - - leader_lp = find_lwp_pid (pid_to_ptid (leader_pid)); + leader_lp = find_lwp_pid (pid_to_ptid (leader_pid)); - if (debug_threads) - debug_printf ("leader_pid=%d, leader_lp!=NULL=%d, " - "num_lwps=%d, zombie=%d\n", - leader_pid, leader_lp!= NULL, num_lwps (leader_pid), - linux_proc_pid_is_zombie (leader_pid)); - - if (leader_lp != NULL && !leader_lp->stopped - /* Check if there are other threads in the group, as we may - have raced with the inferior simply exiting. */ - && !last_thread_of_process_p (leader_pid) - && linux_proc_pid_is_zombie (leader_pid)) - { - /* A leader zombie can mean one of two things: - - - It exited, and there's an exit status pending - available, or only the leader exited (not the whole - program). In the latter case, we can't waitpid the - leader's exit status until all other threads are gone. - - - There are 3 or more threads in the group, and a thread - other than the leader exec'd. On an exec, the Linux - kernel destroys all other threads (except the execing - one) in the thread group, and resets the execing thread's - tid to the tgid. No exit notification is sent for the - execing thread -- from the ptracer's perspective, it - appears as though the execing thread just vanishes. - Until we reap all other threads except the leader and the - execing thread, the leader will be zombie, and the - execing thread will be in `D (disc sleep)'. As soon as - all other threads are reaped, the execing thread changes - it's tid to the tgid, and the previous (zombie) leader - vanishes, giving place to the "new" leader. We could try - distinguishing the exit and exec cases, by waiting once - more, and seeing if something comes out, but it doesn't - sound useful. The previous leader _does_ go away, and - we'll re-add the new one once we see the exec event - (which is just the same as what would happen if the - previous leader did exit voluntarily before some other - thread execs). */ + if (debug_threads) + debug_printf ("leader_pid=%d, leader_lp!=NULL=%d, " + "num_lwps=%d, zombie=%d\n", + leader_pid, leader_lp!= NULL, num_lwps (leader_pid), + linux_proc_pid_is_zombie (leader_pid)); - if (debug_threads) - debug_printf ("CZL: Thread group leader %d zombie " - "(it exited, or another thread execd).\n", - leader_pid); - - delete_lwp (leader_lp); - } - } + if (leader_lp != NULL && !leader_lp->stopped + /* Check if there are other threads in the group, as we may + have raced with the inferior simply exiting. */ + && !last_thread_of_process_p (leader_pid) + && linux_proc_pid_is_zombie (leader_pid)) + { + /* A leader zombie can mean one of two things: + + - It exited, and there's an exit status pending + available, or only the leader exited (not the whole + program). In the latter case, we can't waitpid the + leader's exit status until all other threads are gone. + + - There are 3 or more threads in the group, and a thread + other than the leader exec'd. On an exec, the Linux + kernel destroys all other threads (except the execing + one) in the thread group, and resets the execing thread's + tid to the tgid. No exit notification is sent for the + execing thread -- from the ptracer's perspective, it + appears as though the execing thread just vanishes. + Until we reap all other threads except the leader and the + execing thread, the leader will be zombie, and the + execing thread will be in `D (disc sleep)'. As soon as + all other threads are reaped, the execing thread changes + it's tid to the tgid, and the previous (zombie) leader + vanishes, giving place to the "new" leader. We could try + distinguishing the exit and exec cases, by waiting once + more, and seeing if something comes out, but it doesn't + sound useful. The previous leader _does_ go away, and + we'll re-add the new one once we see the exec event + (which is just the same as what would happen if the + previous leader did exit voluntarily before some other + thread execs). */ + + if (debug_threads) + debug_printf ("CZL: Thread group leader %d zombie " + "(it exited, or another thread execd).\n", + leader_pid); + + delete_lwp (leader_lp); + } + }); } /* Callback for `find_inferior'. Returns the first LWP that is not stopped. ARG is a PTID filter. */ static int -not_stopped_callback (struct inferior_list_entry *entry, void *arg) +not_stopped_callback (thread_info *thread, void *arg) { - struct thread_info *thr = (struct thread_info *) entry; struct lwp_info *lwp; ptid_t filter = *(ptid_t *) arg; - if (!ptid_match (ptid_of (thr), filter)) + if (!ptid_match (ptid_of (thread), filter)) return 0; - lwp = get_thread_lwp (thr); + lwp = get_thread_lwp (thread); if (!lwp->stopped) return 1; @@ -2082,7 +2046,9 @@ handle_tracepoints (struct lwp_info *lwp) lwp_suspended_decr (lwp); gdb_assert (lwp->suspended == 0); - gdb_assert (!stabilizing_threads || lwp->collecting_fast_tracepoint); + gdb_assert (!stabilizing_threads + || (lwp->collecting_fast_tracepoint + != fast_tpoint_collect_result::not_collecting)); if (tpoint_related_event) { @@ -2094,10 +2060,10 @@ handle_tracepoints (struct lwp_info *lwp) return 0; } -/* Convenience wrapper. Returns true if LWP is presently collecting a - fast tracepoint. */ +/* Convenience wrapper. Returns information about LWP's fast tracepoint + collection status. */ -static int +static fast_tpoint_collect_result linux_fast_tracepoint_collecting (struct lwp_info *lwp, struct fast_tpoint_collect_status *status) { @@ -2105,14 +2071,14 @@ linux_fast_tracepoint_collecting (struct lwp_info *lwp, struct thread_info *thread = get_lwp_thread (lwp); if (the_low_target.get_thread_area == NULL) - return 0; + return fast_tpoint_collect_result::not_collecting; /* Get the thread area address. This is used to recognize which thread is which when tracing with the in-process agent library. We don't read anything from the address, and treat it as opaque; it's the address itself that we assume is unique per-thread. */ if ((*the_low_target.get_thread_area) (lwpid_of (thread), &thread_area) == -1) - return 0; + return fast_tpoint_collect_result::not_collecting; return fast_tracepoint_collecting (thread_area, lwp->stop_pc, status); } @@ -2136,14 +2102,14 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat) && agent_loaded_p ()) { struct fast_tpoint_collect_status status; - int r; if (debug_threads) debug_printf ("Checking whether LWP %ld needs to move out of the " "jump pad.\n", lwpid_of (current_thread)); - r = linux_fast_tracepoint_collecting (lwp, &status); + fast_tpoint_collect_result r + = linux_fast_tracepoint_collecting (lwp, &status); if (wstat == NULL || (WSTOPSIG (*wstat) != SIGILL @@ -2153,9 +2119,10 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat) { lwp->collecting_fast_tracepoint = r; - if (r != 0) + if (r != fast_tpoint_collect_result::not_collecting) { - if (r == 1 && lwp->exit_jump_pad_bkpt == NULL) + if (r == fast_tpoint_collect_result::before_insn + && lwp->exit_jump_pad_bkpt == NULL) { /* Haven't executed the original instruction yet. Set breakpoint there, and wait till it's hit, @@ -2181,9 +2148,10 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat) reporting to GDB. Otherwise, it's an IPA lib bug: just report the signal to GDB, and pray for the best. */ - lwp->collecting_fast_tracepoint = 0; + lwp->collecting_fast_tracepoint + = fast_tpoint_collect_result::not_collecting; - if (r != 0 + if (r != fast_tpoint_collect_result::not_collecting && (status.adjusted_insn_addr <= lwp->stop_pc && lwp->stop_pc < status.adjusted_insn_addr_end)) { @@ -2648,9 +2616,8 @@ maybe_hw_step (struct thread_info *thread) to report, but are resumed from the core's perspective. */ static void -resume_stopped_resumed_lwps (struct inferior_list_entry *entry) +resume_stopped_resumed_lwps (thread_info *thread) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lp = get_thread_lwp (thread); if (lp->stopped @@ -2715,7 +2682,8 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid, if (stopping_threads == NOT_STOPPING_THREADS && requested_child->status_pending_p - && requested_child->collecting_fast_tracepoint) + && (requested_child->collecting_fast_tracepoint + != fast_tpoint_collect_result::not_collecting)) { enqueue_one_deferred_signal (requested_child, &requested_child->status_pending); @@ -2889,9 +2857,8 @@ linux_wait_for_event (ptid_t ptid, int *wstatp, int options) /* Count the LWP's that have had events. */ static int -count_events_callback (struct inferior_list_entry *entry, void *data) +count_events_callback (thread_info *thread, void *data) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lp = get_thread_lwp (thread); int *count = (int *) data; @@ -2908,9 +2875,8 @@ count_events_callback (struct inferior_list_entry *entry, void *data) /* Select the LWP (if any) that is currently being single-stepped. */ static int -select_singlestep_lwp_callback (struct inferior_list_entry *entry, void *data) +select_singlestep_lwp_callback (thread_info *thread, void *data) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lp = get_thread_lwp (thread); if (thread->last_status.kind == TARGET_WAITKIND_IGNORE @@ -2924,9 +2890,8 @@ select_singlestep_lwp_callback (struct inferior_list_entry *entry, void *data) /* Select the Nth LWP that has had an event. */ static int -select_event_lwp_callback (struct inferior_list_entry *entry, void *data) +select_event_lwp_callback (thread_info *thread, void *data) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lp = get_thread_lwp (thread); int *selector = (int *) data; @@ -3004,35 +2969,24 @@ select_event_lwp (struct lwp_info **orig_lp) } } -/* Decrement the suspend count of an LWP. */ - -static int -unsuspend_one_lwp (struct inferior_list_entry *entry, void *except) -{ - struct thread_info *thread = (struct thread_info *) entry; - struct lwp_info *lwp = get_thread_lwp (thread); - - /* Ignore EXCEPT. */ - if (lwp == except) - return 0; - - lwp_suspended_decr (lwp); - return 0; -} - /* Decrement the suspend count of all LWPs, except EXCEPT, if non NULL. */ static void unsuspend_all_lwps (struct lwp_info *except) { - find_inferior (&all_threads, unsuspend_one_lwp, except); + for_each_thread ([&] (thread_info *thread) + { + lwp_info *lwp = get_thread_lwp (thread); + + if (lwp != except) + lwp_suspended_decr (lwp); + }); } -static void move_out_of_jump_pad_callback (struct inferior_list_entry *entry); -static int stuck_in_jump_pad_callback (struct inferior_list_entry *entry, - void *data); -static int lwp_running (struct inferior_list_entry *entry, void *data); +static void move_out_of_jump_pad_callback (thread_info *thread); +static bool stuck_in_jump_pad_callback (thread_info *thread); +static int lwp_running (thread_info *thread, void *data); static ptid_t linux_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, int target_options); @@ -3070,13 +3024,8 @@ static ptid_t linux_wait_1 (ptid_t ptid, static void linux_stabilize_threads (void) { - struct thread_info *saved_thread; - struct thread_info *thread_stuck; + thread_info *thread_stuck = find_thread (stuck_in_jump_pad_callback); - thread_stuck - = (struct thread_info *) find_inferior (&all_threads, - stuck_in_jump_pad_callback, - NULL); if (thread_stuck != NULL) { if (debug_threads) @@ -3085,7 +3034,7 @@ linux_stabilize_threads (void) return; } - saved_thread = current_thread; + thread_info *saved_thread = current_thread; stabilizing_threads = 1; @@ -3128,10 +3077,8 @@ linux_stabilize_threads (void) if (debug_threads) { - thread_stuck - = (struct thread_info *) find_inferior (&all_threads, - stuck_in_jump_pad_callback, - NULL); + thread_stuck = find_thread (stuck_in_jump_pad_callback); + if (thread_stuck != NULL) debug_printf ("couldn't stabilize, LWP %ld got stuck in jump pad\n", lwpid_of (thread_stuck)); @@ -3185,7 +3132,7 @@ gdb_catching_syscalls_p (struct lwp_info *event_child) struct thread_info *thread = get_lwp_thread (event_child); struct process_info *proc = get_thread_process (thread); - return !VEC_empty (int, proc->syscalls_to_catch); + return !proc->syscalls_to_catch.empty (); } /* Returns 1 if GDB is interested in the event_child syscall. @@ -3194,21 +3141,19 @@ gdb_catching_syscalls_p (struct lwp_info *event_child) static int gdb_catch_this_syscall_p (struct lwp_info *event_child) { - int i, iter; int sysno; struct thread_info *thread = get_lwp_thread (event_child); struct process_info *proc = get_thread_process (thread); - if (VEC_empty (int, proc->syscalls_to_catch)) + if (proc->syscalls_to_catch.empty ()) return 0; - if (VEC_index (int, proc->syscalls_to_catch, 0) == ANY_SYSCALL) + if (proc->syscalls_to_catch[0] == ANY_SYSCALL) return 1; get_syscall_trapinfo (event_child, &sysno); - for (i = 0; - VEC_iterate (int, proc->syscalls_to_catch, i, iter); - i++) + + for (int iter : proc->syscalls_to_catch) if (iter == sysno) return 1; @@ -3467,20 +3412,22 @@ linux_wait_1 (ptid_t ptid, } } - if (event_child->collecting_fast_tracepoint) + if (event_child->collecting_fast_tracepoint + != fast_tpoint_collect_result::not_collecting) { if (debug_threads) debug_printf ("LWP %ld was trying to move out of the jump pad (%d). " "Check if we're already there.\n", lwpid_of (current_thread), - event_child->collecting_fast_tracepoint); + (int) event_child->collecting_fast_tracepoint); trace_event = 1; event_child->collecting_fast_tracepoint = linux_fast_tracepoint_collecting (event_child, NULL); - if (event_child->collecting_fast_tracepoint != 1) + if (event_child->collecting_fast_tracepoint + != fast_tpoint_collect_result::before_insn) { /* No longer need this breakpoint. */ if (event_child->exit_jump_pad_bkpt != NULL) @@ -3507,7 +3454,8 @@ linux_wait_1 (ptid_t ptid, } } - if (event_child->collecting_fast_tracepoint == 0) + if (event_child->collecting_fast_tracepoint + == fast_tpoint_collect_result::not_collecting) { if (debug_threads) debug_printf ("fast tracepoint finished " @@ -3725,12 +3673,11 @@ linux_wait_1 (ptid_t ptid, { if (event_child->waitstatus.kind != TARGET_WAITKIND_IGNORE) { - char *str; + std::string str + = target_waitstatus_to_string (&event_child->waitstatus); - str = target_waitstatus_to_string (&event_child->waitstatus); debug_printf ("LWP %ld: extended event with waitstatus %s\n", - lwpid_of (get_lwp_thread (event_child)), str); - xfree (str); + lwpid_of (get_lwp_thread (event_child)), str.c_str ()); } if (current_thread->last_resume_kind == resume_step) { @@ -3766,18 +3713,16 @@ linux_wait_1 (ptid_t ptid, { /* In all-stop, a stop reply cancels all previous resume requests. Delete all single-step breakpoints. */ - struct inferior_list_entry *inf, *tmp; - ALL_INFERIORS (&all_threads, inf, tmp) - { - struct thread_info *thread = (struct thread_info *) inf; + find_thread ([&] (thread_info *thread) { + if (has_single_step_breakpoints (thread)) + { + remove_single_step_breakpoints_p = 1; + return true; + } - if (has_single_step_breakpoints (thread)) - { - remove_single_step_breakpoints_p = 1; - break; - } - } + return false; + }); } if (remove_single_step_breakpoints_p) @@ -3794,15 +3739,10 @@ linux_wait_1 (ptid_t ptid, } else { - struct inferior_list_entry *inf, *tmp; - - ALL_INFERIORS (&all_threads, inf, tmp) - { - struct thread_info *thread = (struct thread_info *) inf; - - if (has_single_step_breakpoints (thread)) - delete_single_step_breakpoints (thread); - } + for_each_thread ([] (thread_info *thread){ + if (has_single_step_breakpoints (thread)) + delete_single_step_breakpoints (thread); + }); } unstop_all_lwps (0, event_child); @@ -4055,9 +3995,8 @@ send_sigstop (struct lwp_info *lwp) } static int -send_sigstop_callback (struct inferior_list_entry *entry, void *except) +send_sigstop_callback (thread_info *thread, void *except) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lwp = get_thread_lwp (thread); /* Ignore EXCEPT. */ @@ -4074,10 +4013,8 @@ send_sigstop_callback (struct inferior_list_entry *entry, void *except) /* Increment the suspend count of an LWP, and stop it, if not stopped yet. */ static int -suspend_and_send_sigstop_callback (struct inferior_list_entry *entry, - void *except) +suspend_and_send_sigstop_callback (thread_info *thread, void *except) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lwp = get_thread_lwp (thread); /* Ignore EXCEPT. */ @@ -4086,7 +4023,7 @@ suspend_and_send_sigstop_callback (struct inferior_list_entry *entry, lwp_suspended_inc (lwp); - return send_sigstop_callback (entry, except); + return send_sigstop_callback (thread, except); } static void @@ -4139,7 +4076,7 @@ wait_for_sigstop (void) saved_thread = current_thread; if (saved_thread != NULL) - saved_tid = saved_thread->entry.id; + saved_tid = saved_thread->id; else saved_tid = null_ptid; /* avoid bogus unused warning */ @@ -4167,15 +4104,14 @@ wait_for_sigstop (void) } } -/* Returns true if LWP ENTRY is stopped in a jump pad, and we can't +/* Returns true if THREAD is stopped in a jump pad, and we can't move it out, because we need to report the stop event to GDB. For example, if the user puts a breakpoint in the jump pad, it's because she wants to debug it. */ -static int -stuck_in_jump_pad_callback (struct inferior_list_entry *entry, void *data) +static bool +stuck_in_jump_pad_callback (thread_info *thread) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lwp = get_thread_lwp (thread); if (lwp->suspended != 0) @@ -4192,13 +4128,13 @@ stuck_in_jump_pad_callback (struct inferior_list_entry *entry, void *data) && (gdb_breakpoint_here (lwp->stop_pc) || lwp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT || thread->last_resume_kind == resume_step) - && linux_fast_tracepoint_collecting (lwp, NULL)); + && (linux_fast_tracepoint_collecting (lwp, NULL) + != fast_tpoint_collect_result::not_collecting)); } static void -move_out_of_jump_pad_callback (struct inferior_list_entry *entry) +move_out_of_jump_pad_callback (thread_info *thread) { - struct thread_info *thread = (struct thread_info *) entry; struct thread_info *saved_thread; struct lwp_info *lwp = get_thread_lwp (thread); int *wstat; @@ -4247,9 +4183,8 @@ move_out_of_jump_pad_callback (struct inferior_list_entry *entry) } static int -lwp_running (struct inferior_list_entry *entry, void *data) +lwp_running (thread_info *thread, void *data) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lwp = get_thread_lwp (thread); if (lwp_is_marked_dead (lwp)) @@ -4369,7 +4304,8 @@ single_step (struct lwp_info* lwp) static int lwp_signal_can_be_delivered (struct lwp_info *lwp) { - return !lwp->collecting_fast_tracepoint; + return (lwp->collecting_fast_tracepoint + == fast_tpoint_collect_result::not_collecting); } /* Resume execution of LWP. If STEP is nonzero, single-step it. If @@ -4381,7 +4317,6 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, { struct thread_info *thread = get_lwp_thread (lwp); struct thread_info *saved_thread; - int fast_tp_collecting; int ptrace_request; struct process_info *proc = get_thread_process (thread); @@ -4397,9 +4332,12 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, gdb_assert (lwp->waitstatus.kind == TARGET_WAITKIND_IGNORE); - fast_tp_collecting = lwp->collecting_fast_tracepoint; + fast_tpoint_collect_result fast_tp_collecting + = lwp->collecting_fast_tracepoint; - gdb_assert (!stabilizing_threads || fast_tp_collecting); + gdb_assert (!stabilizing_threads + || (fast_tp_collecting + != fast_tpoint_collect_result::not_collecting)); /* Cancel actions that rely on GDB not changing the PC (e.g., the user used the "jump" command, or "set $pc = foo"). */ @@ -4455,7 +4393,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, if (can_hardware_single_step ()) { - if (fast_tp_collecting == 0) + if (fast_tp_collecting == fast_tpoint_collect_result::not_collecting) { if (step == 0) warning ("BAD - reinserting but not stepping."); @@ -4468,14 +4406,14 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, step = maybe_hw_step (thread); } - if (fast_tp_collecting == 1) + if (fast_tp_collecting == fast_tpoint_collect_result::before_insn) { if (debug_threads) debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad" " (exit-jump-pad-bkpt)\n", lwpid_of (thread)); } - else if (fast_tp_collecting == 2) + else if (fast_tp_collecting == fast_tpoint_collect_result::at_insn) { if (debug_threads) debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad" @@ -4647,9 +4585,8 @@ struct thread_resume_array suspension). */ static int -linux_set_resume_request (struct inferior_list_entry *entry, void *arg) +linux_set_resume_request (thread_info *thread, void *arg) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lwp = get_thread_lwp (thread); int ndx; struct thread_resume_array *r; @@ -4660,7 +4597,7 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg) { ptid_t ptid = r->resume[ndx].thread; if (ptid_equal (ptid, minus_one_ptid) - || ptid_equal (ptid, entry->id) + || ptid == thread->id /* Handle both 'pPID' and 'pPID.-1' as meaning 'all threads of PID'. */ || (ptid_get_pid (ptid) == pid_of (thread) @@ -4700,7 +4637,6 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg) does not yet know are new fork children. */ if (lwp->fork_relative != NULL) { - struct inferior_list_entry *inf, *tmp; struct lwp_info *rel = lwp->fork_relative; if (rel->status_pending_p @@ -4718,7 +4654,7 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg) reported to GDBserver core, but GDB has not pulled the event out of the vStopped queue yet, likewise, ignore the (wildcard) resume request. */ - if (in_queued_stop_replies (entry->id)) + if (in_queued_stop_replies (thread->id)) { if (debug_threads) debug_printf ("not resuming LWP %ld: has queued stop reply\n", @@ -4762,9 +4698,8 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg) Set *FLAG_P if this lwp has an interesting status pending. */ static int -resume_status_pending_p (struct inferior_list_entry *entry, void *flag_p) +resume_status_pending_p (thread_info *thread, void *flag_p) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lwp = get_thread_lwp (thread); /* LWPs which will not be resumed are not interesting, because @@ -4784,9 +4719,8 @@ resume_status_pending_p (struct inferior_list_entry *entry, void *flag_p) inferior's regcache. */ static int -need_step_over_p (struct inferior_list_entry *entry, void *dummy) +need_step_over_p (thread_info *thread, void *dummy) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lwp = get_thread_lwp (thread); struct thread_info *saved_thread; CORE_ADDR pc; @@ -4969,7 +4903,7 @@ start_step_over (struct lwp_info *lwp) linux_resume_one_lwp (lwp, step, 0, NULL); /* Require next event from this LWP. */ - step_over_bkpt = thread->entry.id; + step_over_bkpt = thread->id; return 1; } @@ -5062,9 +4996,8 @@ complete_ongoing_step_over (void) they should be re-issued if necessary. */ static int -linux_resume_one_thread (struct inferior_list_entry *entry, void *arg) +linux_resume_one_thread (thread_info *thread, void *arg) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lwp = get_thread_lwp (thread); int leave_all_stopped = * (int *) arg; int leave_pending; @@ -5155,7 +5088,7 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg) if (debug_threads) debug_printf ("resuming LWP %ld\n", lwpid_of (thread)); - proceed_one_lwp (entry, NULL); + proceed_one_lwp (thread, NULL); } else { @@ -5247,9 +5180,8 @@ linux_resume (struct thread_resume *resume_info, size_t n) on that particular thread, and leave all others stopped. */ static int -proceed_one_lwp (struct inferior_list_entry *entry, void *except) +proceed_one_lwp (thread_info *thread, void *except) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lwp = get_thread_lwp (thread); int step; @@ -5294,7 +5226,8 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except) if (thread->last_resume_kind == resume_stop && lwp->pending_signals_to_report == NULL - && lwp->collecting_fast_tracepoint == 0) + && (lwp->collecting_fast_tracepoint + == fast_tpoint_collect_result::not_collecting)) { /* We haven't reported this LWP as stopped yet (otherwise, the last_status.kind check above would catch it, and we wouldn't @@ -5345,9 +5278,8 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except) } static int -unsuspend_and_proceed_one_lwp (struct inferior_list_entry *entry, void *except) +unsuspend_and_proceed_one_lwp (thread_info *thread, void *except) { - struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lwp = get_thread_lwp (thread); if (lwp == except) @@ -5355,7 +5287,7 @@ unsuspend_and_proceed_one_lwp (struct inferior_list_entry *entry, void *except) lwp_suspended_decr (lwp); - return proceed_one_lwp (entry, except); + return proceed_one_lwp (thread, except); } /* When we finish a step-over, set threads running again. If there's @@ -6453,35 +6385,6 @@ linux_supports_exec_events (void) return linux_supports_traceexec (); } -/* Callback for 'find_inferior'. Set the (possibly changed) ptrace - options for the specified lwp. */ - -static int -reset_lwp_ptrace_options_callback (struct inferior_list_entry *entry, - void *args) -{ - struct thread_info *thread = (struct thread_info *) entry; - struct lwp_info *lwp = get_thread_lwp (thread); - - if (!lwp->stopped) - { - /* Stop the lwp so we can modify its ptrace options. */ - lwp->must_set_ptrace_flags = 1; - linux_stop_lwp (lwp); - } - else - { - /* Already stopped; go ahead and set the ptrace options. */ - struct process_info *proc = find_process_pid (pid_of (thread)); - int options = linux_low_ptrace_options (proc->attached); - - linux_enable_event_reporting (lwpid_of (thread), options); - lwp->must_set_ptrace_flags = 0; - } - - return 0; -} - /* Target hook for 'handle_new_gdb_connection'. Causes a reset of the ptrace flags for all inferiors. This is in case the new GDB connection doesn't support the same set of events that the previous one did. */ @@ -6489,10 +6392,27 @@ reset_lwp_ptrace_options_callback (struct inferior_list_entry *entry, static void linux_handle_new_gdb_connection (void) { - pid_t pid; - /* Request that all the lwps reset their ptrace options. */ - find_inferior (&all_threads, reset_lwp_ptrace_options_callback , &pid); + for_each_thread ([] (thread_info *thread) + { + struct lwp_info *lwp = get_thread_lwp (thread); + + if (!lwp->stopped) + { + /* Stop the lwp so we can modify its ptrace options. */ + lwp->must_set_ptrace_flags = 1; + linux_stop_lwp (lwp); + } + else + { + /* Already stopped; go ahead and set the ptrace options. */ + struct process_info *proc = find_process_pid (pid_of (thread)); + int options = linux_low_ptrace_options (proc->attached); + + linux_enable_event_reporting (lwpid_of (thread), options); + lwp->must_set_ptrace_flags = 0; + } + }); } static int @@ -7277,7 +7197,6 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf, { /* 6x the size for xml_escape_text below. */ size_t len = 6 * strlen ((char *) libname); - char *name; if (!header_done) { @@ -7296,12 +7215,11 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf, p = document + document_len; } - name = xml_escape_text ((char *) libname); + std::string name = xml_escape_text ((char *) libname); p += sprintf (p, "", - name, (unsigned long) lm_addr, + name.c_str (), (unsigned long) lm_addr, (unsigned long) l_addr, (unsigned long) l_ld); - free (name); } } @@ -7694,6 +7612,11 @@ static struct target_ops linux_target_ops = { linux_supports_software_single_step, linux_supports_catch_syscall, linux_get_ipa_tdesc_idx, +#if USE_THREAD_DB + thread_db_thread_handle, +#else + NULL, +#endif }; #ifdef HAVE_LINUX_REGSETS