From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 79sWJv9F4Wkg5RwAWB0awg (envelope-from ) for ; Thu, 16 Apr 2026 16:26:39 -0400 Received: by simark.ca (Postfix, from userid 112) id 621F31E0CA; Thu, 16 Apr 2026 16:26:39 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.3 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id BA8E91E04F for ; Thu, 16 Apr 2026 16:26:35 -0400 (EDT) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id F17C14C91774 for ; Thu, 16 Apr 2026 20:26:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F17C14C91774 Received: from simark.ca (simark.ca [158.69.221.121]) by sourceware.org (Postfix) with ESMTPS id A4D6F4BA903C for ; Thu, 16 Apr 2026 20:24:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A4D6F4BA903C Authentication-Results: sourceware.org; dmarc=fail (p=none dis=none) header.from=efficios.com Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=efficios.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A4D6F4BA903C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=158.69.221.121 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776371052; cv=none; b=rNQii/N8GiNvZBhiwykD3ZdwUvtmVNBeOkdbXx+MFf1XNWCPdP/YP6Di+MHl5ynDIxB4fQUSvtoyJe8VL5OUz13YiiDrfNOsKSjxAsLvguA9MKl2jjYx7CEYmHkmhNnSKT3rX5xecZlX9vE+nfMv1LK1T4sloH5FsBaTEdSKwvA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776371052; c=relaxed/simple; bh=pCX/GiCYqrjKoCg5Y4I7vvcuwzsPZTUQmwn5jfLTJtI=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=tnfZJ391yN5wLmu03PFJJ3+8q1ExjMQXF6w6uihqL20lyXSMCvQ6pmtjqXbl9ZrjNKWu8rqqIUncq/3293i+cQJM3HnZIenHTq3XX8q+e9no81Lzhmv2BZrMpM2lNoJ5C/f536guzdwRm3xB2kWos/uALAtjRhTzguOZ/rCX8wM= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A4D6F4BA903C Received: by simark.ca (Postfix) id 77BCA1E0DA; Thu, 16 Apr 2026 16:24:10 -0400 (EDT) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 05/11] gdb, gdbserver: split iterate_over_lwps in for_each_lwp and find_lwp Date: Thu, 16 Apr 2026 16:16:15 -0400 Message-ID: <20260416202408.422441-6-simon.marchi@efficios.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260416202408.422441-1-simon.marchi@efficios.com> References: <20260416202408.422441-1-simon.marchi@efficios.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org From: Simon Marchi Even though it works, I have always been mildly annoyed by iterate_over_lwps being used for both iterating over all lwps and finding one lwp matching a criterion. I think it would be clearer to have two functions for the two use cases. Then it would be 100% clear at the call site what the intention is. It would be clear that a callback returning bool is meant to be a predicate for the find function, while a callback returning void is meant to be a callback for the "for each" function. Therefore, split iterate_over_lwps in two: - find_lwp to find the first lwp matching a boolean predicate (and the given ptid filter) - for_each_lwp to apply a function on all lwps (optionally filtering by ptid or pid) The callbacks given to for_each_lwp can now return void. Introduce some overloads for for_each_lwp, for the various common use cases: - filtering by ptid - filtering by pid - no ptid/pid filter find_lwp and two overloads of for_each_lwp are actually only used in gdb/linux-nat.c, so make them local to that file. Only the pid variant of for_each_lwp is used in shared code. The pattern used in this patch serves as the basis for subsequent patches that split other "iterate over" functions the same way. Change-Id: I49d3af0916622300cc81e3c32d22e1aff13cf38f --- gdb/arm-linux-nat.c | 38 ++-- gdb/linux-nat.c | 276 +++++++++++++++-------------- gdb/nat/aarch64-linux-hw-point.c | 17 +- gdb/nat/linux-nat.h | 16 +- gdb/nat/loongarch-linux-hw-point.c | 18 +- gdb/nat/x86-linux-dregs.c | 15 +- gdb/ppc-linux-nat.c | 22 +-- gdb/s390-linux-nat.c | 22 +-- gdbserver/linux-low.cc | 20 +-- 9 files changed, 208 insertions(+), 236 deletions(-) diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c index 9d7bd6e09c97..b3d4ce1ec37a 100644 --- a/gdb/arm-linux-nat.c +++ b/gdb/arm-linux-nat.c @@ -960,7 +960,7 @@ arm_linux_hw_breakpoint_equal (const struct arm_linux_hw_breakpoint *p1, /* Callback to mark a watch-/breakpoint to be updated in all threads of the current process. */ -static int +static void update_registers_callback (struct lwp_info *lwp, int watch, int index) { if (lwp->arch_private == NULL) @@ -977,8 +977,6 @@ update_registers_callback (struct lwp_info *lwp, int watch, int index) we can update its breakpoint registers. */ if (!lwp->stopped) linux_stop_lwp (lwp); - - return 0; } /* Insert the hardware breakpoint (WATCHPOINT = 0) or watchpoint (WATCHPOINT @@ -987,14 +985,10 @@ static void arm_linux_insert_hw_breakpoint1 (const struct arm_linux_hw_breakpoint* bpt, int watchpoint) { - int pid; - ptid_t pid_ptid; + int pid = inferior_ptid.pid (); gdb_byte count, i; struct arm_linux_hw_breakpoint* bpts; - pid = inferior_ptid.pid (); - pid_ptid = ptid_t (pid); - if (watchpoint) { count = arm_linux_get_hw_watchpoint_count (); @@ -1010,12 +1004,11 @@ arm_linux_insert_hw_breakpoint1 (const struct arm_linux_hw_breakpoint* bpt, if (!arm_hwbp_control_is_enabled (bpts[i].control)) { bpts[i] = *bpt; - iterate_over_lwps (pid_ptid, - [=] (struct lwp_info *info) - { - return update_registers_callback (info, watchpoint, - i); - }); + for_each_lwp (pid, + [=] (struct lwp_info *info) + { + update_registers_callback (info, watchpoint, i); + }); break; } @@ -1028,14 +1021,10 @@ static void arm_linux_remove_hw_breakpoint1 (const struct arm_linux_hw_breakpoint *bpt, int watchpoint) { - int pid; + int pid = inferior_ptid.pid (); gdb_byte count, i; - ptid_t pid_ptid; struct arm_linux_hw_breakpoint* bpts; - pid = inferior_ptid.pid (); - pid_ptid = ptid_t (pid); - if (watchpoint) { count = arm_linux_get_hw_watchpoint_count (); @@ -1051,12 +1040,11 @@ arm_linux_remove_hw_breakpoint1 (const struct arm_linux_hw_breakpoint *bpt, if (arm_linux_hw_breakpoint_equal (bpt, bpts + i)) { bpts[i].control = arm_hwbp_control_disable (bpts[i].control); - iterate_over_lwps (pid_ptid, - [=] (struct lwp_info *info) - { - return update_registers_callback (info, watchpoint, - i); - }); + for_each_lwp (pid, + [=] (struct lwp_info *info) + { + update_registers_callback (info, watchpoint, i); + }); break; } diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 362ef5f1cb75..15fca3f6d35e 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -278,7 +278,7 @@ static bool report_thread_events; static int kill_lwp (int lwpid, int signo); -static int stop_callback (struct lwp_info *lp); +static void stop_callback (struct lwp_info *lp); static void block_child_signals (sigset_t *prev_mask); static void restore_child_signals_mask (sigset_t *prev_mask); @@ -795,8 +795,9 @@ linux_nat_target::pass_signals /* Prototypes for local functions. */ -static int stop_wait_callback (struct lwp_info *lp); -static int resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid); +static void stop_wait_callback (struct lwp_info *lp); +static void resume_stopped_resumed_lwps (struct lwp_info *lp, + const ptid_t wait_ptid); static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp); @@ -928,19 +929,51 @@ find_lwp_pid (ptid_t ptid) /* See nat/linux-nat.h. */ -lwp_info * -iterate_over_lwps (ptid_t filter, iterate_over_lwps_ftype callback) +void +for_each_lwp (int pid, for_each_lwp_ftype callback) { for (lwp_info &lp : all_lwps_safe ()) - { - if (lp.ptid.matches (filter)) - { - if (callback (&lp) != 0) - return &lp; - } - } + if (lp.ptid.pid () == pid) + callback (&lp); +} - return NULL; +/* Iterate over all LWPs, calling CALLBACK for every LWP. + + Only consider the LWPs matching FILTER. */ + +static void +for_each_lwp (ptid_t filter, for_each_lwp_ftype callback) +{ + for (lwp_info &lp : all_lwps_safe ()) + if (lp.ptid.matches (filter)) + callback (&lp); +} + +/* Iterate over all LWPs, calling CALLBACK for every LWP. */ + +static void +for_each_lwp (for_each_lwp_ftype callback) +{ + for (lwp_info &lp : all_lwps_safe ()) + callback (&lp); +} + +/* Function type for the CALLBACK argument of find_lwp. */ + +using find_lwp_ftype = gdb::function_view; + +/* Find the first LWP matching FILTER and the criteria specified by CALLBACK. + + Return nullptr if no matching LWP is found. */ + +static lwp_info * +find_lwp (ptid_t filter, find_lwp_ftype callback) +{ + for (lwp_info &lp : all_lwps_safe ()) + if (lp.ptid.matches (filter) && callback (&lp)) + return &lp; + + return nullptr; } /* Update our internal state when changing from one checkpoint to @@ -1220,14 +1253,13 @@ linux_nat_target::attach (const char *args, int from_tty) { /* Failed to attach to some LWP. Detach any we've already attached to. */ - iterate_over_lwps (ptid_t (ptid.pid ()), - [] (struct lwp_info *lwp) -> int - { - /* Ignore errors when detaching. */ - ptrace (PTRACE_DETACH, lwp->ptid.lwp (), 0, 0); - delete_lwp (lwp->ptid); - return 0; - }); + for_each_lwp (ptid.pid (), + [] (struct lwp_info *lwp) + { + /* Ignore errors when detaching. */ + ptrace (PTRACE_DETACH, lwp->ptid.lwp (), 0, 0); + delete_lwp (lwp->ptid); + }); target_terminal::ours (); target_mourn_inferior (inferior_ptid); @@ -1236,18 +1268,17 @@ linux_nat_target::attach (const char *args, int from_tty) } /* Add all the LWPs to gdb's thread list. */ - iterate_over_lwps (ptid_t (ptid.pid ()), - [] (struct lwp_info *lwp) -> int - { - if (lwp->ptid.pid () != lwp->ptid.lwp ()) - { - add_thread (linux_target, lwp->ptid); - set_state (linux_target, lwp->ptid, THREAD_RUNNING); - set_internal_state (linux_target, lwp->ptid, - THREAD_INT_RUNNING); - } - return 0; - }); + for_each_lwp (ptid.pid (), + [] (struct lwp_info *lwp) + { + if (lwp->ptid.pid () != lwp->ptid.lwp ()) + { + add_thread (linux_target, lwp->ptid); + set_state (linux_target, lwp->ptid, THREAD_RUNNING); + set_internal_state (linux_target, lwp->ptid, + THREAD_INT_RUNNING); + } + }); } /* Ptrace-detach the thread with pid PID. */ @@ -1513,7 +1544,7 @@ detach_one_lwp (struct lwp_info *lp, int *signo_p) delete_lwp (lp->ptid); } -static int +static void detach_callback (struct lwp_info *lp) { /* We don't actually detach from the thread group leader just yet. @@ -1521,7 +1552,6 @@ detach_callback (struct lwp_info *lp) before we're able to reap the leader. */ if (lp->ptid.lwp () != lp->ptid.pid ()) detach_one_lwp (lp, NULL); - return 0; } void @@ -1537,17 +1567,17 @@ linux_nat_target::detach (inferior *inf, int from_tty) /* Stop all threads before detaching. ptrace requires that the thread is stopped to successfully detach. */ - iterate_over_lwps (ptid_t (pid), stop_callback); + for_each_lwp (pid, stop_callback); /* ... and wait until all of them have reported back that they're no longer running. */ - iterate_over_lwps (ptid_t (pid), stop_wait_callback); + for_each_lwp (pid, stop_wait_callback); /* We can now safely remove breakpoints. We don't this in earlier in common code because this target doesn't currently support writing memory while the inferior is running. */ remove_breakpoints_inf (current_inferior ()); - iterate_over_lwps (ptid_t (pid), detach_callback); + for_each_lwp (pid, detach_callback); /* We have detached from everything except the main thread now, so should only have one thread left. However, in non-stop mode the @@ -1708,16 +1738,16 @@ resume_lwp (struct lwp_info *lp, int step, enum gdb_signal signo) lp->ptid.to_string ().c_str ()); } -/* Callback for iterate_over_lwps. If LWP is EXCEPT, do nothing. - Resume LWP with the last stop signal, if it is in pass state. */ +/* Callback for for_each_lwp. If LP is EXCEPT, do nothing. + Resume LP with the last stop signal, if it is in pass state. */ -static int +static void linux_nat_resume_callback (struct lwp_info *lp, struct lwp_info *except) { enum gdb_signal signo = GDB_SIGNAL_0; if (lp == except) - return 0; + return; if (lp->stopped) { @@ -1732,23 +1762,20 @@ linux_nat_resume_callback (struct lwp_info *lp, struct lwp_info *except) } resume_lwp (lp, 0, signo); - return 0; } -static int +static void resume_clear_callback (struct lwp_info *lp) { lp->resumed = 0; lp->last_resume_kind = resume_stop; - return 0; } -static int +static void resume_set_callback (struct lwp_info *lp) { lp->resumed = 1; lp->last_resume_kind = resume_continue; - return 0; } void @@ -1765,7 +1792,7 @@ linux_nat_target::resume (ptid_t scope_ptid, int step, enum gdb_signal signo) /* Mark the lwps we're resuming as resumed and update their last_resume_kind to resume_continue. */ - iterate_over_lwps (scope_ptid, resume_set_callback); + for_each_lwp (scope_ptid, resume_set_callback); lp = find_lwp_pid (inferior_ptid); gdb_assert (lp != NULL); @@ -1818,9 +1845,9 @@ linux_nat_target::resume (ptid_t scope_ptid, int step, enum gdb_signal signo) /* No use iterating unless we're resuming other threads. */ if (scope_ptid != lp->ptid) - iterate_over_lwps (scope_ptid, [=] (struct lwp_info *info) + for_each_lwp (scope_ptid, [=] (struct lwp_info *info) { - return linux_nat_resume_callback (info, lp); + linux_nat_resume_callback (info, lp); }); linux_nat_debug_printf ("%s %s, %s (resume event thread)", @@ -2367,7 +2394,7 @@ wait_lwp (struct lwp_info *lp) /* Send a SIGSTOP to LP. */ -static int +static void stop_callback (struct lwp_info *lp) { if (!lp->stopped && !lp->signalled) @@ -2385,8 +2412,6 @@ stop_callback (struct lwp_info *lp) lp->signalled = 1; gdb_assert (lp->status == 0); } - - return 0; } /* Request a stop on LWP. */ @@ -2403,11 +2428,11 @@ void linux_stop_and_wait_all_lwps (void) { /* Stop all LWP's ... */ - iterate_over_lwps (minus_one_ptid, stop_callback); + for_each_lwp (stop_callback); /* ... and wait until all of them have reported back that they're no longer running. */ - iterate_over_lwps (minus_one_ptid, stop_wait_callback); + for_each_lwp (stop_wait_callback); } /* See linux-nat.h */ @@ -2415,11 +2440,10 @@ linux_stop_and_wait_all_lwps (void) void linux_unstop_all_lwps (void) { - iterate_over_lwps (minus_one_ptid, - [] (struct lwp_info *info) - { - return resume_stopped_resumed_lwps (info, minus_one_ptid); - }); + for_each_lwp ([] (struct lwp_info *info) + { + resume_stopped_resumed_lwps (info, minus_one_ptid); + }); } /* Return non-zero if LWP PID has a pending SIGINT. */ @@ -2440,7 +2464,7 @@ linux_nat_has_pending_sigint (int pid) /* Set a flag in LP indicating that we should ignore its next SIGINT. */ -static int +static void set_ignore_sigint (struct lwp_info *lp) { /* If a thread has a pending SIGINT, consume it; otherwise, set a @@ -2450,8 +2474,6 @@ set_ignore_sigint (struct lwp_info *lp) lp->status = 0; else lp->ignore_sigint = 1; - - return 0; } /* If LP does not have a SIGINT pending, then clear the ignore_sigint flag. @@ -2540,7 +2562,7 @@ linux_nat_target::low_status_is_event (int status) /* Wait until LP is stopped. */ -static int +static void stop_wait_callback (struct lwp_info *lp) { inferior *inf = find_inferior_ptid (linux_target, lp->ptid); @@ -2548,7 +2570,7 @@ stop_wait_callback (struct lwp_info *lp) /* If this is a vfork parent, bail out, it is not going to report any SIGSTOP until the vfork is done with. */ if (inf->vfork_child != NULL) - return 0; + return; if (!lp->stopped) { @@ -2556,7 +2578,7 @@ stop_wait_callback (struct lwp_info *lp) status = wait_lwp (lp); if (status == 0) - return 0; + return; if (lp->ignore_sigint && WIFSTOPPED (status) && WSTOPSIG (status) == SIGINT) @@ -2608,8 +2630,6 @@ stop_wait_callback (struct lwp_info *lp) } } } - - return 0; } /* Get the inferior associated to LWP. Must be called with an LWP that has @@ -2623,20 +2643,20 @@ lwp_inferior (const lwp_info *lwp) return inf; } -/* Return non-zero if LP has a wait status pending. Discard the +/* Return true if LP has a wait status pending. Discard the pending event and resume the LWP if the event that originally caused the stop became uninteresting. */ -static int +static bool status_callback (struct lwp_info *lp) { /* Only report a pending wait status if we pretend that this has indeed been resumed. */ if (!lp->resumed) - return 0; + return false; if (!lwp_status_pending_p (lp)) - return 0; + return false; if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT || lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT) @@ -2664,16 +2684,16 @@ status_callback (struct lwp_info *lp) lp->status = 0; linux_resume_one_lwp (lp, lp->step, GDB_SIGNAL_0); - return 0; + return false; } } - return 1; + return true; } /* Count the LWP's that have had events. */ -static int +static void count_events_callback (struct lwp_info *lp, int *count) { gdb_assert (count != NULL); @@ -2681,20 +2701,14 @@ count_events_callback (struct lwp_info *lp, int *count) /* Select only resumed LWPs that have an event pending. */ if (lp->resumed && lwp_status_pending_p (lp)) (*count)++; - - return 0; } /* Select the LWP (if any) that is currently being single-stepped. */ -static int +static bool select_singlestep_lwp_callback (struct lwp_info *lp) { - if (lp->last_resume_kind == resume_step - && lp->status != 0) - return 1; - else - return 0; + return lp->last_resume_kind == resume_step && lp->status != 0; } /* Returns true if LP has a status pending. */ @@ -2710,7 +2724,7 @@ lwp_status_pending_p (struct lwp_info *lp) /* Select the Nth LWP that has had an event. */ -static int +static bool select_event_lwp_callback (struct lwp_info *lp, int *selector) { gdb_assert (selector != NULL); @@ -2718,9 +2732,9 @@ select_event_lwp_callback (struct lwp_info *lp, int *selector) /* Select only resumed LWPs that have an event pending. */ if (lp->resumed && lwp_status_pending_p (lp)) if ((*selector)-- == 0) - return 1; + return true; - return 0; + return false; } /* Called when the LWP stopped for a signal/trap. If it stopped for a @@ -2888,7 +2902,7 @@ select_event_lwp (ptid_t filter, struct lwp_info **orig_lp, int *status) signal. */ if (!target_is_non_stop_p ()) { - event_lp = iterate_over_lwps (filter, select_singlestep_lwp_callback); + event_lp = find_lwp (filter, select_singlestep_lwp_callback); if (event_lp != NULL) { linux_nat_debug_printf ("Select single-step %s", @@ -2901,11 +2915,11 @@ select_event_lwp (ptid_t filter, struct lwp_info **orig_lp, int *status) /* Pick one at random, out of those which have had events. */ /* First see how many events we have. */ - iterate_over_lwps (filter, - [&] (struct lwp_info *info) - { - return count_events_callback (info, &num_events); - }); + for_each_lwp (filter, + [&] (struct lwp_info *info) + { + count_events_callback (info, &num_events); + }); gdb_assert (num_events > 0); /* Now randomly pick a LWP out of those that have had @@ -2918,13 +2932,12 @@ select_event_lwp (ptid_t filter, struct lwp_info **orig_lp, int *status) num_events, random_selector); event_lp - = (iterate_over_lwps - (filter, - [&] (struct lwp_info *info) + = find_lwp (filter, + [&] (struct lwp_info *info) { return select_event_lwp_callback (info, &random_selector); - })); + }); } if (event_lp != NULL) @@ -2940,7 +2953,7 @@ select_event_lwp (ptid_t filter, struct lwp_info **orig_lp, int *status) /* Return non-zero if LP has been resumed. */ -static int +static bool resumed_callback (struct lwp_info *lp) { return lp->resumed; @@ -3156,7 +3169,7 @@ linux_nat_filter_event (int lwpid, int status) will receive it - unless they're using CLONE_THREAD to share signals. Since we only want to report it once, we mark it as ignored for all LWPs except this one. */ - iterate_over_lwps (ptid_t (lp->ptid.pid ()), set_ignore_sigint); + for_each_lwp (lp->ptid.pid (), set_ignore_sigint); lp->ignore_sigint = 0; } else @@ -3335,7 +3348,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, block_child_signals (&prev_mask); /* First check if there is a LWP with a wait status pending. */ - lp = iterate_over_lwps (ptid, status_callback); + lp = find_lwp (ptid, status_callback); if (lp != NULL) { linux_nat_debug_printf ("Using pending wait status %s for %s.", @@ -3385,15 +3398,14 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, /* Now that we've pulled all events out of the kernel, resume LWPs that don't have an interesting event to report. */ - iterate_over_lwps (minus_one_ptid, - [] (struct lwp_info *info) - { - return resume_stopped_resumed_lwps (info, minus_one_ptid); - }); + for_each_lwp ([] (struct lwp_info *info) + { + resume_stopped_resumed_lwps (info, minus_one_ptid); + }); /* ... and find an LWP with a status to report to the core, if any. */ - lp = iterate_over_lwps (ptid, status_callback); + lp = find_lwp (ptid, status_callback); if (lp != NULL) break; @@ -3403,7 +3415,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, /* If there are no resumed children left, bail. We'd be stuck forever in the sigsuspend call below otherwise. */ - if (iterate_over_lwps (ptid, resumed_callback) == NULL) + if (find_lwp (ptid, resumed_callback) == NULL) { linux_nat_debug_printf ("exit (no resumed LWP)"); @@ -3440,11 +3452,11 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, if (!target_is_non_stop_p ()) { /* Now stop all other LWP's ... */ - iterate_over_lwps (minus_one_ptid, stop_callback); + for_each_lwp (stop_callback); /* ... and wait until all of them have reported back that they're no longer running. */ - iterate_over_lwps (minus_one_ptid, stop_wait_callback); + for_each_lwp (stop_wait_callback); } /* If we're not waiting for a specific LWP, choose an event LWP from @@ -3464,7 +3476,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, { /* In all-stop, from the core's perspective, all LWPs are now stopped until a new resume action is sent over. */ - iterate_over_lwps (minus_one_ptid, resume_clear_callback); + for_each_lwp (resume_clear_callback); } else { @@ -3511,7 +3523,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, /* Resume LWPs that are currently stopped without any pending status to report, but are resumed from the core's perspective. */ -static int +static void resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid) { inferior *inf = lwp_inferior (lp); @@ -3570,8 +3582,6 @@ resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid) throw; } } - - return 0; } ptid_t @@ -3597,11 +3607,10 @@ linux_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, meanwhile the event became uninteresting. Don't bother resuming LWPs we're not going to wait for if they'd stop immediately. */ if (target_is_non_stop_p ()) - iterate_over_lwps (minus_one_ptid, - [=] (struct lwp_info *info) - { - return resume_stopped_resumed_lwps (info, ptid); - }); + for_each_lwp ([=] (struct lwp_info *info) + { + resume_stopped_resumed_lwps (info, ptid); + }); event_ptid = linux_nat_wait_1 (ptid, ourstatus, target_options); @@ -3680,27 +3689,25 @@ kill_wait_one_lwp (pid_t pid) gdb_assert (res == -1 && errno == ECHILD); } -/* Callback for iterate_over_lwps. */ +/* Callback for for_each_lwp. */ -static int +static void kill_callback (struct lwp_info *lp) { kill_one_lwp (lp->ptid.lwp ()); - return 0; } -/* Callback for iterate_over_lwps. */ +/* Callback for for_each_lwp. */ -static int +static void kill_wait_callback (struct lwp_info *lp) { kill_wait_one_lwp (lp->ptid.lwp ()); - return 0; } /* Kill the fork/clone child of LP if it has an unfollowed child. */ -static int +static void kill_unfollowed_child_callback (lwp_info *lp) { std::optional ws = get_pending_child_status (lp); @@ -3718,19 +3725,17 @@ kill_unfollowed_child_callback (lwp_info *lp) if (ws->kind () != TARGET_WAITKIND_THREAD_CLONED) linux_target->low_forget_process (child_pid); } - - return 0; } void linux_nat_target::kill () { - ptid_t pid_ptid (inferior_ptid.pid ()); + int pid = inferior_ptid.pid (); /* If we're stopped while forking/cloning and we haven't followed yet, kill the child task. We need to do this first because the parent will be sleeping if this is a vfork. */ - iterate_over_lwps (pid_ptid, kill_unfollowed_child_callback); + for_each_lwp (pid, kill_unfollowed_child_callback); if (forks_exist_p (current_inferior ())) linux_fork_killall (current_inferior ()); @@ -3738,16 +3743,16 @@ linux_nat_target::kill () { /* Stop all threads before killing them, since ptrace requires that the thread is stopped to successfully PTRACE_KILL. */ - iterate_over_lwps (pid_ptid, stop_callback); + for_each_lwp (pid, stop_callback); /* ... and wait until all of them have reported back that they're no longer running. */ - iterate_over_lwps (pid_ptid, stop_wait_callback); + for_each_lwp (pid, stop_wait_callback); /* Kill all LWP's ... */ - iterate_over_lwps (pid_ptid, kill_callback); + for_each_lwp (pid, kill_callback); /* ... and wait until we've flushed all events. */ - iterate_over_lwps (pid_ptid, kill_wait_callback); + for_each_lwp (pid, kill_wait_callback); } target_mourn_inferior (inferior_ptid); @@ -4486,7 +4491,7 @@ linux_nat_target::async (bool enable) /* Stop an LWP, and push a GDB_SIGNAL_0 stop status if no other event came out. */ -static int +static void linux_nat_stop_lwp (struct lwp_info *lwp) { if (!lwp->stopped) @@ -4499,7 +4504,7 @@ linux_nat_stop_lwp (struct lwp_info *lwp) { linux_nat_debug_printf ("already stopping LWP %ld at GDB's request", lwp->ptid.lwp ()); - return 0; + return; } stop_callback (lwp); @@ -4519,14 +4524,13 @@ linux_nat_stop_lwp (struct lwp_info *lwp) lwp->ptid.to_string ().c_str ()); } } - return 0; } void linux_nat_target::stop (ptid_t ptid) { LINUX_NAT_SCOPED_DEBUG_ENTER_EXIT; - iterate_over_lwps (ptid, linux_nat_stop_lwp); + for_each_lwp (ptid, linux_nat_stop_lwp); } /* Return the cached value of the processor core for thread PTID. */ diff --git a/gdb/nat/aarch64-linux-hw-point.c b/gdb/nat/aarch64-linux-hw-point.c index 1e11d28e9066..b4d74ab8dc2b 100644 --- a/gdb/nat/aarch64-linux-hw-point.c +++ b/gdb/nat/aarch64-linux-hw-point.c @@ -43,7 +43,7 @@ bool kernel_supports_any_contiguous_range = true; N.B. The actual updating of hardware debug registers is not carried out until the moment the thread is resumed. */ -static int +static void debug_reg_change_callback (struct lwp_info *lwp, int is_watchpoint, unsigned int idx) { @@ -92,8 +92,6 @@ debug_reg_change_callback (struct lwp_info *lwp, int is_watchpoint, phex (info->dr_changed_bp, 8), phex (info->dr_changed_wp, 8)); } - - return 0; } /* Notify each thread that their IDXth breakpoint/watchpoint register @@ -105,14 +103,11 @@ void aarch64_notify_debug_reg_change (ptid_t ptid, int is_watchpoint, unsigned int idx) { - ptid_t pid_ptid = ptid_t (ptid.pid ()); - - iterate_over_lwps (pid_ptid, [=] (struct lwp_info *info) - { - return debug_reg_change_callback (info, - is_watchpoint, - idx); - }); + for_each_lwp (ptid.pid (), [=] (struct lwp_info *info) + { + debug_reg_change_callback (info, is_watchpoint, + idx); + }); } /* Reconfigure STATE to be compatible with Linux kernels with the PR diff --git a/gdb/nat/linux-nat.h b/gdb/nat/linux-nat.h index 42c0467191fe..4414749b93de 100644 --- a/gdb/nat/linux-nat.h +++ b/gdb/nat/linux-nat.h @@ -46,17 +46,15 @@ extern tribool have_ptrace_getregset; extern ptid_t current_lwp_ptid (void); -/* Function type for the CALLBACK argument of iterate_over_lwps. */ -using iterate_over_lwps_ftype = gdb::function_view; +/* Function type for the CALLBACK argument of for_each_lwp. */ -/* Iterate over all LWPs. Calls CALLBACK with its second argument set - to DATA for every LWP in the list. If CALLBACK returns nonzero for - a particular LWP, return a pointer to the structure describing that - LWP immediately. Otherwise return NULL. This function must be - provided by the client. */ +using for_each_lwp_ftype = gdb::function_view; -extern lwp_info *iterate_over_lwps (ptid_t filter, - iterate_over_lwps_ftype callback); +/* Iterate over all LWPs, calling CALLBACK for every LWP. + + Only consider the LWPs with that pid. */ + +extern void for_each_lwp (int pid, for_each_lwp_ftype callback); /* Return the ptid of LWP. */ diff --git a/gdb/nat/loongarch-linux-hw-point.c b/gdb/nat/loongarch-linux-hw-point.c index 68eee8fb7754..be867e758edf 100644 --- a/gdb/nat/loongarch-linux-hw-point.c +++ b/gdb/nat/loongarch-linux-hw-point.c @@ -44,7 +44,7 @@ N.B. The actual updating of hardware debug registers is not carried out until the moment the thread is resumed. */ -static int +static void loongarch_dr_change_callback (struct lwp_info *lwp, int is_watchpoint, unsigned int idx) { @@ -93,8 +93,6 @@ loongarch_dr_change_callback (struct lwp_info *lwp, int is_watchpoint, phex (info->dr_changed_bp, 8), phex (info->dr_changed_wp, 8)); } - - return 0; } /* Notify each thread that their IDXth breakpoint/watchpoint register @@ -106,14 +104,12 @@ void loongarch_notify_debug_reg_change (ptid_t ptid, int is_watchpoint, unsigned int idx) { - ptid_t pid_ptid = ptid_t (ptid.pid ()); - - iterate_over_lwps (pid_ptid, [=] (struct lwp_info *info) - { - return loongarch_dr_change_callback (info, - is_watchpoint, - idx); - }); + for_each_lwp (ptid.pid (), [=] (struct lwp_info *info) + { + loongarch_dr_change_callback (info, + is_watchpoint, + idx); + }); } /* Call ptrace to set the thread TID's hardware breakpoint/watchpoint diff --git a/gdb/nat/x86-linux-dregs.c b/gdb/nat/x86-linux-dregs.c index abdfa50edb93..ea8de511d5c4 100644 --- a/gdb/nat/x86-linux-dregs.c +++ b/gdb/nat/x86-linux-dregs.c @@ -69,21 +69,18 @@ x86_linux_dr_set (ptid_t ptid, int regnum, unsigned long value) perror_with_name (_("Couldn't write debug register")); } -/* Callback for iterate_over_lwps. Mark that our local mirror of +/* Callback for for_each_lwp. Mark that our local mirror of LWP's debug registers has been changed, and cause LWP to stop if it isn't already. Values are written from our local mirror to the actual debug registers immediately prior to LWP resuming. */ -static int +static void update_debug_registers_callback (struct lwp_info *lwp) { lwp_set_debug_registers_changed (lwp, 1); if (!lwp_is_stopped (lwp)) linux_stop_lwp (lwp); - - /* Continue the iteration. */ - return 0; } /* See nat/x86-linux-dregs.h. */ @@ -101,11 +98,9 @@ x86_linux_dr_get_addr (int regnum) void x86_linux_dr_set_addr (int regnum, CORE_ADDR addr) { - ptid_t pid_ptid = ptid_t (current_lwp_ptid ().pid ()); - gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR); - iterate_over_lwps (pid_ptid, update_debug_registers_callback); + for_each_lwp (current_lwp_ptid ().pid (), update_debug_registers_callback); } /* See nat/x86-linux-dregs.h. */ @@ -121,9 +116,7 @@ x86_linux_dr_get_control (void) void x86_linux_dr_set_control (unsigned long control) { - ptid_t pid_ptid = ptid_t (current_lwp_ptid ().pid ()); - - iterate_over_lwps (pid_ptid, update_debug_registers_callback); + for_each_lwp (current_lwp_ptid ().pid (), update_debug_registers_callback); } /* See nat/x86-linux-dregs.h. */ diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c index b077a1d0cf42..102a51c85090 100644 --- a/gdb/ppc-linux-nat.c +++ b/gdb/ppc-linux-nat.c @@ -3103,18 +3103,18 @@ ppc_linux_nat_target::mark_debug_registers_changed (pid_t pid) /* We do this in two passes to make sure all threads are marked even if we get an exception when stopping one of them. */ - iterate_over_lwps (ptid_t (pid), - [this] (struct lwp_info *lp) -> int { - this->mark_thread_stale (lp); - return 0; - }); + for_each_lwp (pid, + [this] (struct lwp_info *lp) + { + this->mark_thread_stale (lp); + }); - iterate_over_lwps (ptid_t (pid), - [] (struct lwp_info *lp) -> int { - if (!lwp_is_stopped (lp)) - linux_stop_lwp (lp); - return 0; - }); + for_each_lwp (pid, + [] (struct lwp_info *lp) + { + if (!lwp_is_stopped (lp)) + linux_stop_lwp (lp); + }); } /* Register a hardware breakpoint or watchpoint BP for the pid PID, then diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c index 5bee2b1e1128..6ef524a310cb 100644 --- a/gdb/s390-linux-nat.c +++ b/gdb/s390-linux-nat.c @@ -822,25 +822,21 @@ s390_linux_nat_target::low_delete_thread (struct arch_lwp_info *arch_lwp) /* Iterator callback for s390_refresh_per_info. */ -static int +static void s390_refresh_per_info_cb (struct lwp_info *lp) { s390_mark_per_info_changed (lp); if (!lwp_is_stopped (lp)) linux_stop_lwp (lp); - return 0; } /* Make sure that threads are stopped and mark PER info as changed. */ -static int +static void s390_refresh_per_info (void) { - ptid_t pid_ptid = ptid_t (current_lwp_ptid ().pid ()); - - iterate_over_lwps (pid_ptid, s390_refresh_per_info_cb); - return 0; + for_each_lwp (current_lwp_ptid ().pid (), s390_refresh_per_info_cb); } int @@ -856,7 +852,8 @@ s390_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len, area.hi_addr = addr + len - 1; state->watch_areas.push_back (area); - return s390_refresh_per_info (); + s390_refresh_per_info (); + return 0; } int @@ -874,7 +871,8 @@ s390_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len, if (area.lo_addr == addr && area.hi_addr == addr + len - 1) { unordered_remove (state->watch_areas, ix); - return s390_refresh_per_info (); + s390_refresh_per_info (); + return 0; } } @@ -908,7 +906,8 @@ s390_linux_nat_target::insert_hw_breakpoint (struct gdbarch *gdbarch, state = s390_get_debug_reg_state (inferior_ptid.pid ()); state->break_areas.push_back (area); - return s390_refresh_per_info (); + s390_refresh_per_info (); + return 0; } /* Implement the "remove_hw_breakpoint" target_ops method. */ @@ -927,7 +926,8 @@ s390_linux_nat_target::remove_hw_breakpoint (struct gdbarch *gdbarch, if (area.lo_addr == bp_tgt->placed_address) { unordered_remove (state->break_areas, ix); - return s390_refresh_per_info (); + s390_refresh_per_info (); + return 0; } } diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc index 022e8415fda8..b4ec524dbbff 100644 --- a/gdbserver/linux-low.cc +++ b/gdbserver/linux-low.cc @@ -1768,20 +1768,18 @@ num_lwps (process_info *process) /* See nat/linux-nat.h. */ -lwp_info * -iterate_over_lwps (ptid_t filter, iterate_over_lwps_ftype callback) +void +for_each_lwp (int pid, for_each_lwp_ftype callback) { - thread_info *thread = find_thread (filter, [&] (thread_info *thr_arg) + process_info *process = find_process_pid (pid); + + if (process == nullptr) + return; + + process->for_each_thread ([&] (thread_info *thread) { - lwp_info *lwp = get_thread_lwp (thr_arg); - - return callback (lwp); + callback (get_thread_lwp (thread)); }); - - if (thread == NULL) - return NULL; - - return get_thread_lwp (thread); } bool -- 2.53.0