mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 09:08:59 +00:00
Make single-step breakpoints be per-thread
This patch finally makes each thread have its own set of single-step breakpoints. This paves the way to have multiple threads software single-stepping, though this patch doesn't flip that switch on yet. That'll be done on a subsequent patch. gdb/ 2014-10-15 Pedro Alves <palves@redhat.com> * breakpoint.c (single_step_breakpoints): Delete global. (insert_single_step_breakpoint): Adjust to store the breakpoint pointer in the current thread. (single_step_breakpoints_inserted, remove_single_step_breakpoints) (cancel_single_step_breakpoints): Delete functions. (breakpoint_has_location_inserted_here): Make extern. (single_step_breakpoint_inserted_here_p): Adjust to walk the breakpoint list. * breakpoint.h (breakpoint_has_location_inserted_here): New declaration. (single_step_breakpoints_inserted, remove_single_step_breakpoints) (cancel_single_step_breakpoints): Remove declarations. * gdbthread.h (struct thread_control_state) <single_step_breakpoints>: New field. (delete_single_step_breakpoints) (thread_has_single_step_breakpoints_set) (thread_has_single_step_breakpoint_here): New declarations. * infrun.c (follow_exec): Also clear the single-step breakpoints. (singlestep_breakpoints_inserted_p, singlestep_ptid) (singlestep_pc): Delete globals. (infrun_thread_ptid_changed): Remove references to removed globals. (resume_cleanups): Delete the current thread's single-step breakpoints. (maybe_software_singlestep): Remove references to removed globals. (resume): Adjust to use thread_has_single_step_breakpoints_set and delete_single_step_breakpoints. (init_wait_for_inferior): Remove references to removed globals. (delete_thread_infrun_breakpoints): Delete the thread's single-step breakpoints too. (delete_just_stopped_threads_infrun_breakpoints): Don't delete single-step breakpoints here. (delete_stopped_threads_single_step_breakpoints): New function. (adjust_pc_after_break): Adjust to use thread_has_single_step_breakpoints_set. (handle_inferior_event): Remove references to removed globals. Use delete_stopped_threads_single_step_breakpoints. (handle_signal_stop): Adjust to per-thread single-step breakpoints. Swap test order to do cheaper tests first. (switch_back_to_stepped_thread): Extend debug output. Remove references to removed globals. * record-full.c (record_full_wait_1): Adjust to per-thread single-step breakpoints. * thread.c (delete_single_step_breakpoints) (thread_has_single_step_breakpoints_set) (thread_has_single_step_breakpoint_here): New functions. (clear_thread_inferior_resources): Also delete the thread's single-step breakpoints.
This commit is contained in:
@@ -325,11 +325,6 @@ static struct breakpoint_ops bkpt_probe_breakpoint_ops;
|
||||
/* Dynamic printf class type. */
|
||||
struct breakpoint_ops dprintf_breakpoint_ops;
|
||||
|
||||
/* One (or perhaps two) breakpoints used for software single
|
||||
stepping. */
|
||||
|
||||
static struct breakpoint *single_step_breakpoints;
|
||||
|
||||
/* The style in which to perform a dynamic printf. This is a user
|
||||
option because different output options have different tradeoffs;
|
||||
if GDB does the printing, there is better error handling if there
|
||||
@@ -15319,57 +15314,24 @@ insert_single_step_breakpoint (struct gdbarch *gdbarch,
|
||||
struct symtab_and_line sal;
|
||||
CORE_ADDR pc = next_pc;
|
||||
|
||||
if (single_step_breakpoints == NULL)
|
||||
single_step_breakpoints = new_single_step_breakpoint (tp->num, gdbarch);
|
||||
if (tp->control.single_step_breakpoints == NULL)
|
||||
{
|
||||
tp->control.single_step_breakpoints
|
||||
= new_single_step_breakpoint (tp->num, gdbarch);
|
||||
}
|
||||
|
||||
sal = find_pc_line (pc, 0);
|
||||
sal.pc = pc;
|
||||
sal.section = find_pc_overlay (pc);
|
||||
sal.explicit_pc = 1;
|
||||
add_location_to_breakpoint (single_step_breakpoints, &sal);
|
||||
add_location_to_breakpoint (tp->control.single_step_breakpoints, &sal);
|
||||
|
||||
update_global_location_list (UGLL_INSERT);
|
||||
}
|
||||
|
||||
/* Check if the breakpoints used for software single stepping
|
||||
were inserted or not. */
|
||||
/* See breakpoint.h. */
|
||||
|
||||
int
|
||||
single_step_breakpoints_inserted (void)
|
||||
{
|
||||
return (single_step_breakpoints != NULL);
|
||||
}
|
||||
|
||||
/* Remove and delete any breakpoints used for software single step. */
|
||||
|
||||
void
|
||||
remove_single_step_breakpoints (void)
|
||||
{
|
||||
gdb_assert (single_step_breakpoints != NULL);
|
||||
|
||||
delete_breakpoint (single_step_breakpoints);
|
||||
|
||||
single_step_breakpoints = NULL;
|
||||
}
|
||||
|
||||
/* Delete software single step breakpoints without removing them from
|
||||
the inferior. This is intended to be used if the inferior's address
|
||||
space where they were inserted is already gone, e.g. after exit or
|
||||
exec. */
|
||||
|
||||
void
|
||||
cancel_single_step_breakpoints (void)
|
||||
{
|
||||
/* We don't really need to (or should) delete them here. After an
|
||||
exit, breakpoint_init_inferior deletes it. After an exec,
|
||||
update_breakpoints_after_exec does it. Just clear our
|
||||
reference. */
|
||||
single_step_breakpoints = NULL;
|
||||
}
|
||||
|
||||
/* Check whether any location of BP is inserted at PC. */
|
||||
|
||||
static int
|
||||
breakpoint_has_location_inserted_here (struct breakpoint *bp,
|
||||
struct address_space *aspace,
|
||||
CORE_ADDR pc)
|
||||
@@ -15391,9 +15353,15 @@ int
|
||||
single_step_breakpoint_inserted_here_p (struct address_space *aspace,
|
||||
CORE_ADDR pc)
|
||||
{
|
||||
return (single_step_breakpoints != NULL
|
||||
&& breakpoint_has_location_inserted_here (single_step_breakpoints,
|
||||
aspace, pc));
|
||||
struct breakpoint *bpt;
|
||||
|
||||
ALL_BREAKPOINTS (bpt)
|
||||
{
|
||||
if (bpt->type == bp_single_step
|
||||
&& breakpoint_has_location_inserted_here (bpt, aspace, pc))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns 0 if 'bp' is NOT a syscall catchpoint,
|
||||
|
||||
Reference in New Issue
Block a user