aboutsummaryrefslogtreecommitdiff
path: root/gdb/infrun.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r--gdb/infrun.c88
1 files changed, 34 insertions, 54 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 27d78b1..346e6c8 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -537,10 +537,10 @@ how to step past a permanent breakpoint on this architecture. Try using\n\
a command like `return' or `jump' to continue execution."));
}
- if (SOFTWARE_SINGLE_STEP_P () && step)
+ if (step && gdbarch_software_single_step_p (current_gdbarch))
{
/* Do it the hard way, w/temp breakpoints */
- if (SOFTWARE_SINGLE_STEP (get_current_frame ()))
+ if (gdbarch_software_single_step (current_gdbarch, get_current_frame ()))
{
/* ...and don't ask hardware to do it. */
step = 0;
@@ -1190,52 +1190,33 @@ adjust_pc_after_break (struct execution_control_state *ecs)
breakpoint_pc = read_pc_pid (ecs->ptid) - gdbarch_decr_pc_after_break
(current_gdbarch);
- if (SOFTWARE_SINGLE_STEP_P ())
- {
- /* When using software single-step, a SIGTRAP can only indicate
- an inserted breakpoint. This actually makes things
- easier. */
- if (singlestep_breakpoints_inserted_p)
- /* When software single stepping, the instruction at [prev_pc]
- is never a breakpoint, but the instruction following
- [prev_pc] (in program execution order) always is. Assume
- that following instruction was reached and hence a software
- breakpoint was hit. */
- write_pc_pid (breakpoint_pc, ecs->ptid);
- else if (software_breakpoint_inserted_here_p (breakpoint_pc))
- /* The inferior was free running (i.e., no single-step
- breakpoints inserted) and it hit a software breakpoint. */
- write_pc_pid (breakpoint_pc, ecs->ptid);
- }
- else
+ /* Check whether there actually is a software breakpoint inserted
+ at that location. */
+ if (software_breakpoint_inserted_here_p (breakpoint_pc))
{
- /* When using hardware single-step, a SIGTRAP is reported for
- both a completed single-step and a software breakpoint. Need
- to differentiate between the two as the latter needs
- adjusting but the former does not.
+ /* When using hardware single-step, a SIGTRAP is reported for both
+ a completed single-step and a software breakpoint. Need to
+ differentiate between the two, as the latter needs adjusting
+ but the former does not.
- When the thread to be examined does not match the current thread
- context we can't use currently_stepping, so assume no
- single-stepping in this case. */
- if (ptid_equal (ecs->ptid, inferior_ptid) && currently_stepping (ecs))
- {
- if (prev_pc == breakpoint_pc
- && software_breakpoint_inserted_here_p (breakpoint_pc))
- /* Hardware single-stepped a software breakpoint (as
- occures when the inferior is resumed with PC pointing
- at not-yet-hit software breakpoint). Since the
- breakpoint really is executed, the inferior needs to be
- backed up to the breakpoint address. */
- write_pc_pid (breakpoint_pc, ecs->ptid);
- }
- else
- {
- if (software_breakpoint_inserted_here_p (breakpoint_pc))
- /* The inferior was free running (i.e., no hardware
- single-step and no possibility of a false SIGTRAP) and
- hit a software breakpoint. */
- write_pc_pid (breakpoint_pc, ecs->ptid);
- }
+ The SIGTRAP can be due to a completed hardware single-step only if
+ - we didn't insert software single-step breakpoints
+ - the thread to be examined is still the current thread
+ - this thread is currently being stepped
+
+ If any of these events did not occur, we must have stopped due
+ to hitting a software breakpoint, and have to back up to the
+ breakpoint address.
+
+ As a special case, we could have hardware single-stepped a
+ software breakpoint. In this case (prev_pc == breakpoint_pc),
+ we also need to back up to the breakpoint address. */
+
+ if (singlestep_breakpoints_inserted_p
+ || !ptid_equal (ecs->ptid, inferior_ptid)
+ || !currently_stepping (ecs)
+ || prev_pc == breakpoint_pc)
+ write_pc_pid (breakpoint_pc, ecs->ptid);
}
}
@@ -1379,7 +1360,7 @@ handle_inferior_event (struct execution_control_state *ecs)
(LONGEST) ecs->ws.value.integer));
gdb_flush (gdb_stdout);
target_mourn_inferior ();
- singlestep_breakpoints_inserted_p = 0; /* SOFTWARE_SINGLE_STEP_P() */
+ singlestep_breakpoints_inserted_p = 0;
stop_print_frame = 0;
stop_stepping (ecs);
return;
@@ -1399,7 +1380,7 @@ handle_inferior_event (struct execution_control_state *ecs)
target_mourn_inferior ();
print_stop_reason (SIGNAL_EXITED, stop_signal);
- singlestep_breakpoints_inserted_p = 0; /* SOFTWARE_SINGLE_STEP_P() */
+ singlestep_breakpoints_inserted_p = 0;
stop_stepping (ecs);
return;
@@ -1555,8 +1536,7 @@ handle_inferior_event (struct execution_control_state *ecs)
if (stepping_past_singlestep_breakpoint)
{
- gdb_assert (SOFTWARE_SINGLE_STEP_P ()
- && singlestep_breakpoints_inserted_p);
+ gdb_assert (singlestep_breakpoints_inserted_p);
gdb_assert (ptid_equal (singlestep_ptid, ecs->ptid));
gdb_assert (!ptid_equal (singlestep_ptid, saved_singlestep_ptid));
@@ -1605,7 +1585,7 @@ handle_inferior_event (struct execution_control_state *ecs)
if (!breakpoint_thread_match (stop_pc, ecs->ptid))
thread_hop_needed = 1;
}
- else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ else if (singlestep_breakpoints_inserted_p)
{
/* We have not context switched yet, so this should be true
no matter which thread hit the singlestep breakpoint. */
@@ -1676,7 +1656,7 @@ handle_inferior_event (struct execution_control_state *ecs)
/* Saw a breakpoint, but it was hit by the wrong thread.
Just continue. */
- if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ if (singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
remove_single_step_breakpoints ();
@@ -1725,7 +1705,7 @@ handle_inferior_event (struct execution_control_state *ecs)
return;
}
}
- else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ else if (singlestep_breakpoints_inserted_p)
{
sw_single_step_trap_p = 1;
ecs->random_signal = 0;
@@ -1747,7 +1727,7 @@ handle_inferior_event (struct execution_control_state *ecs)
deprecated_context_hook (pid_to_thread_id (ecs->ptid));
}
- if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ if (singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
remove_single_step_breakpoints ();