mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2026-08-27 00:26:02 -04:00
gdb, gdbserver: split iterate_over_lwps into for_each_lwp and find_lwp
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 Approved-By: Andrew Burgess <aburgess@redhat.com>
This commit is contained in:
parent
e71ab8393e
commit
24bac805d7
9 changed files with 208 additions and 236 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
276
gdb/linux-nat.c
276
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<bool (lwp_info *lwp)>;
|
||||
|
||||
/* 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<target_waitstatus> 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. */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<int (lwp_info *lwp)>;
|
||||
/* 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<void (lwp_info *lwp)>;
|
||||
|
||||
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. */
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue