gdb: use intrusive_list for linux-nat lwp_list
Replace the manually maintained linked list of lwp_info objects with intrusive_list. Replace the ALL_LWPS macro with all_lwps, which returns a range. Add all_lwps_safe as well, for use in iterate_over_lwps, which currently iterates in a safe manner. Change-Id: I355313502510acc0103f5eaf2fbde80897d6376c
This commit is contained in:
parent
676362df18
commit
901b98215e
5 changed files with 46 additions and 53 deletions
|
@ -589,7 +589,6 @@ ia64_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
|
||||||
enum target_hw_bp_type type,
|
enum target_hw_bp_type type,
|
||||||
struct expression *cond)
|
struct expression *cond)
|
||||||
{
|
{
|
||||||
struct lwp_info *lp;
|
|
||||||
int idx;
|
int idx;
|
||||||
long dbr_addr, dbr_mask;
|
long dbr_addr, dbr_mask;
|
||||||
int max_watchpoints = 4;
|
int max_watchpoints = 4;
|
||||||
|
@ -630,7 +629,8 @@ ia64_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
|
||||||
|
|
||||||
debug_registers[2 * idx] = dbr_addr;
|
debug_registers[2 * idx] = dbr_addr;
|
||||||
debug_registers[2 * idx + 1] = dbr_mask;
|
debug_registers[2 * idx + 1] = dbr_mask;
|
||||||
ALL_LWPS (lp)
|
|
||||||
|
for (const lwp_info *lp : all_lwps ())
|
||||||
{
|
{
|
||||||
store_debug_register_pair (lp->ptid, idx, &dbr_addr, &dbr_mask);
|
store_debug_register_pair (lp->ptid, idx, &dbr_addr, &dbr_mask);
|
||||||
enable_watchpoints_in_psr (lp->ptid);
|
enable_watchpoints_in_psr (lp->ptid);
|
||||||
|
@ -657,14 +657,12 @@ ia64_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
|
||||||
dbr_mask = debug_registers[2 * idx + 1];
|
dbr_mask = debug_registers[2 * idx + 1];
|
||||||
if ((dbr_mask & (0x3UL << 62)) && addr == (CORE_ADDR) dbr_addr)
|
if ((dbr_mask & (0x3UL << 62)) && addr == (CORE_ADDR) dbr_addr)
|
||||||
{
|
{
|
||||||
struct lwp_info *lp;
|
|
||||||
|
|
||||||
debug_registers[2 * idx] = 0;
|
debug_registers[2 * idx] = 0;
|
||||||
debug_registers[2 * idx + 1] = 0;
|
debug_registers[2 * idx + 1] = 0;
|
||||||
dbr_addr = 0;
|
dbr_addr = 0;
|
||||||
dbr_mask = 0;
|
dbr_mask = 0;
|
||||||
|
|
||||||
ALL_LWPS (lp)
|
for (const lwp_info *lp : all_lwps ())
|
||||||
store_debug_register_pair (lp->ptid, idx, &dbr_addr, &dbr_mask);
|
store_debug_register_pair (lp->ptid, idx, &dbr_addr, &dbr_mask);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -421,9 +421,8 @@ static int
|
||||||
num_lwps (int pid)
|
num_lwps (int pid)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
struct lwp_info *lp;
|
|
||||||
|
|
||||||
for (lp = lwp_list; lp; lp = lp->next)
|
for (const lwp_info *lp ATTRIBUTE_UNUSED : all_lwps ())
|
||||||
if (lp->ptid.pid () == pid)
|
if (lp->ptid.pid () == pid)
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
|
@ -700,17 +699,31 @@ lwp_lwpid_htab_add_lwp (struct lwp_info *lp)
|
||||||
creation order. This order is assumed in some cases. E.g.,
|
creation order. This order is assumed in some cases. E.g.,
|
||||||
reaping status after killing alls lwps of a process: the leader LWP
|
reaping status after killing alls lwps of a process: the leader LWP
|
||||||
must be reaped last. */
|
must be reaped last. */
|
||||||
struct lwp_info *lwp_list;
|
|
||||||
|
static intrusive_list<lwp_info> lwp_list;
|
||||||
|
|
||||||
|
/* See linux-nat.h. */
|
||||||
|
|
||||||
|
lwp_info_range
|
||||||
|
all_lwps ()
|
||||||
|
{
|
||||||
|
return lwp_info_range (lwp_list.begin ());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See linux-nat.h. */
|
||||||
|
|
||||||
|
lwp_info_safe_range
|
||||||
|
all_lwps_safe ()
|
||||||
|
{
|
||||||
|
return lwp_info_safe_range (lwp_list.begin ());
|
||||||
|
}
|
||||||
|
|
||||||
/* Add LP to sorted-by-reverse-creation-order doubly-linked list. */
|
/* Add LP to sorted-by-reverse-creation-order doubly-linked list. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lwp_list_add (struct lwp_info *lp)
|
lwp_list_add (struct lwp_info *lp)
|
||||||
{
|
{
|
||||||
lp->next = lwp_list;
|
lwp_list.push_front (*lp);
|
||||||
if (lwp_list != NULL)
|
|
||||||
lwp_list->prev = lp;
|
|
||||||
lwp_list = lp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove LP from sorted-by-reverse-creation-order doubly-linked
|
/* Remove LP from sorted-by-reverse-creation-order doubly-linked
|
||||||
|
@ -720,12 +733,7 @@ static void
|
||||||
lwp_list_remove (struct lwp_info *lp)
|
lwp_list_remove (struct lwp_info *lp)
|
||||||
{
|
{
|
||||||
/* Remove from sorted-by-creation-order list. */
|
/* Remove from sorted-by-creation-order list. */
|
||||||
if (lp->next != NULL)
|
lwp_list.erase (lwp_list.iterator_to (*lp));
|
||||||
lp->next->prev = lp->prev;
|
|
||||||
if (lp->prev != NULL)
|
|
||||||
lp->prev->next = lp->next;
|
|
||||||
if (lp == lwp_list)
|
|
||||||
lwp_list = lp->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -922,12 +930,8 @@ struct lwp_info *
|
||||||
iterate_over_lwps (ptid_t filter,
|
iterate_over_lwps (ptid_t filter,
|
||||||
gdb::function_view<iterate_over_lwps_ftype> callback)
|
gdb::function_view<iterate_over_lwps_ftype> callback)
|
||||||
{
|
{
|
||||||
struct lwp_info *lp, *lpnext;
|
for (lwp_info *lp : all_lwps_safe ())
|
||||||
|
|
||||||
for (lp = lwp_list; lp; lp = lpnext)
|
|
||||||
{
|
{
|
||||||
lpnext = lp->next;
|
|
||||||
|
|
||||||
if (lp->ptid.matches (filter))
|
if (lp->ptid.matches (filter))
|
||||||
{
|
{
|
||||||
if (callback (lp) != 0)
|
if (callback (lp) != 0)
|
||||||
|
@ -3715,8 +3719,6 @@ linux_nat_target::thread_alive (ptid_t ptid)
|
||||||
void
|
void
|
||||||
linux_nat_target::update_thread_list ()
|
linux_nat_target::update_thread_list ()
|
||||||
{
|
{
|
||||||
struct lwp_info *lwp;
|
|
||||||
|
|
||||||
/* We add/delete threads from the list as clone/exit events are
|
/* We add/delete threads from the list as clone/exit events are
|
||||||
processed, so just try deleting exited threads still in the
|
processed, so just try deleting exited threads still in the
|
||||||
thread list. */
|
thread list. */
|
||||||
|
@ -3724,7 +3726,7 @@ linux_nat_target::update_thread_list ()
|
||||||
|
|
||||||
/* Update the processor core that each lwp/thread was last seen
|
/* Update the processor core that each lwp/thread was last seen
|
||||||
running on. */
|
running on. */
|
||||||
ALL_LWPS (lwp)
|
for (lwp_info *lwp : all_lwps ())
|
||||||
{
|
{
|
||||||
/* Avoid accessing /proc if the thread hasn't run since we last
|
/* Avoid accessing /proc if the thread hasn't run since we last
|
||||||
time we fetched the thread's core. Accessing /proc becomes
|
time we fetched the thread's core. Accessing /proc becomes
|
||||||
|
@ -3948,7 +3950,7 @@ linux_proc_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||||
|
|
||||||
/* Iterate over LWPs of the current inferior, trying to access
|
/* Iterate over LWPs of the current inferior, trying to access
|
||||||
memory through one of them. */
|
memory through one of them. */
|
||||||
for (lwp_info *lp = lwp_list; lp != nullptr; lp = lp->next)
|
for (lwp_info *lp : all_lwps ())
|
||||||
{
|
{
|
||||||
if (lp->ptid.pid () != cur_pid)
|
if (lp->ptid.pid () != cur_pid)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -196,11 +196,9 @@ extern linux_nat_target *linux_target;
|
||||||
|
|
||||||
struct arch_lwp_info;
|
struct arch_lwp_info;
|
||||||
|
|
||||||
/* Structure describing an LWP. This is public only for the purposes
|
/* Structure describing an LWP. */
|
||||||
of ALL_LWPS; target-specific code should generally not access it
|
|
||||||
directly. */
|
|
||||||
|
|
||||||
struct lwp_info
|
struct lwp_info : intrusive_list_node<lwp_info>
|
||||||
{
|
{
|
||||||
lwp_info (ptid_t ptid)
|
lwp_info (ptid_t ptid)
|
||||||
: ptid (ptid)
|
: ptid (ptid)
|
||||||
|
@ -283,27 +281,26 @@ struct lwp_info
|
||||||
|
|
||||||
/* Arch-specific additions. */
|
/* Arch-specific additions. */
|
||||||
struct arch_lwp_info *arch_private = nullptr;
|
struct arch_lwp_info *arch_private = nullptr;
|
||||||
|
|
||||||
/* Previous and next pointers in doubly-linked list of known LWPs,
|
|
||||||
sorted by reverse creation order. */
|
|
||||||
struct lwp_info *prev = nullptr;
|
|
||||||
struct lwp_info *next = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The global list of LWPs, for ALL_LWPS. Unlike the threads list,
|
/* lwp_info iterator and range types. */
|
||||||
there is always at least one LWP on the list while the GNU/Linux
|
|
||||||
native target is active. */
|
using lwp_info_iterator
|
||||||
extern struct lwp_info *lwp_list;
|
= reference_to_pointer_iterator<intrusive_list<lwp_info>::iterator>;
|
||||||
|
using lwp_info_range = iterator_range<lwp_info_iterator>;
|
||||||
|
using lwp_info_safe_range = basic_safe_range<lwp_info_range>;
|
||||||
|
|
||||||
|
/* Get an iterable range over all lwps. */
|
||||||
|
|
||||||
|
lwp_info_range all_lwps ();
|
||||||
|
|
||||||
|
/* Same as the above, but safe against deletion while iterating. */
|
||||||
|
|
||||||
|
lwp_info_safe_range all_lwps_safe ();
|
||||||
|
|
||||||
/* Does the current host support PTRACE_GETREGSET? */
|
/* Does the current host support PTRACE_GETREGSET? */
|
||||||
extern enum tribool have_ptrace_getregset;
|
extern enum tribool have_ptrace_getregset;
|
||||||
|
|
||||||
/* Iterate over each active thread (light-weight process). */
|
|
||||||
#define ALL_LWPS(LP) \
|
|
||||||
for ((LP) = lwp_list; \
|
|
||||||
(LP) != NULL; \
|
|
||||||
(LP) = (LP)->next)
|
|
||||||
|
|
||||||
/* Called from the LWP layer to inform the thread_db layer that PARENT
|
/* Called from the LWP layer to inform the thread_db layer that PARENT
|
||||||
spawned CHILD. Both LWPs are currently stopped. This function
|
spawned CHILD. Both LWPs are currently stopped. This function
|
||||||
does whatever is required to have the child LWP under the
|
does whatever is required to have the child LWP under the
|
||||||
|
|
|
@ -920,13 +920,12 @@ try_thread_db_load_1 (struct thread_db_info *info)
|
||||||
|
|
||||||
if (info->td_ta_thr_iter_p == NULL)
|
if (info->td_ta_thr_iter_p == NULL)
|
||||||
{
|
{
|
||||||
struct lwp_info *lp;
|
|
||||||
int pid = inferior_ptid.pid ();
|
int pid = inferior_ptid.pid ();
|
||||||
thread_info *curr_thread = inferior_thread ();
|
thread_info *curr_thread = inferior_thread ();
|
||||||
|
|
||||||
linux_stop_and_wait_all_lwps ();
|
linux_stop_and_wait_all_lwps ();
|
||||||
|
|
||||||
ALL_LWPS (lp)
|
for (const lwp_info *lp : all_lwps ())
|
||||||
if (lp->ptid.pid () == pid)
|
if (lp->ptid.pid () == pid)
|
||||||
thread_from_lwp (curr_thread, lp->ptid);
|
thread_from_lwp (curr_thread, lp->ptid);
|
||||||
|
|
||||||
|
|
|
@ -632,12 +632,9 @@ mips_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
|
||||||
static int
|
static int
|
||||||
write_watchpoint_regs (void)
|
write_watchpoint_regs (void)
|
||||||
{
|
{
|
||||||
struct lwp_info *lp;
|
for (const lwp_info *lp : all_lwps ())
|
||||||
int tid;
|
|
||||||
|
|
||||||
ALL_LWPS (lp)
|
|
||||||
{
|
{
|
||||||
tid = lp->ptid.lwp ();
|
int tid = lp->ptid.lwp ();
|
||||||
if (ptrace (PTRACE_SET_WATCH_REGS, tid, &watch_mirror, NULL) == -1)
|
if (ptrace (PTRACE_SET_WATCH_REGS, tid, &watch_mirror, NULL) == -1)
|
||||||
perror_with_name (_("Couldn't write debug register"));
|
perror_with_name (_("Couldn't write debug register"));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue