--- breakpoint.c | 13 +++++++++++++ breakpoint.h | 1 + record.c | 33 ++++++++++++++++++++++++++++++--- 3 files changed, 44 insertions(+), 3 deletions(-) --- a/breakpoint.c +++ b/breakpoint.c @@ -9624,6 +9624,19 @@ insert_single_step_breakpoint (struct gd paddress (gdbarch, next_pc)); } +/* Check if the breakpoints used for software single stepping + were inserted or not. */ + +int +single_step_breakpoints_inserted (void) +{ + if (single_step_breakpoints[0] != NULL + || single_step_breakpoints[1] != NULL) + return 1; + + return 0; +} + /* Remove and delete any breakpoints used for software single step. */ void --- a/breakpoint.h +++ b/breakpoint.h @@ -944,6 +944,7 @@ extern int remove_hw_watchpoints (void); twice before remove is called. */ extern void insert_single_step_breakpoint (struct gdbarch *, struct address_space *, CORE_ADDR); +extern int single_step_breakpoints_inserted (void); extern void remove_single_step_breakpoints (void); /* Manage manual breakpoints, separate from the normal chain of --- a/record.c +++ b/record.c @@ -1002,9 +1002,23 @@ record_resume (struct target_ops *ops, p if (!RECORD_IS_REPLAY) { + struct gdbarch *gdbarch = target_thread_architecture (ptid); + record_message (get_current_regcache (), signal); record_beneath_to_resume (record_beneath_to_resume_ops, ptid, 1, signal); + + if (gdbarch_software_single_step_p (gdbarch)) + { + if (!inserted_single_step_breakpoint_p ()) + gdbarch_software_single_step (gdbarch, get_current_frame ()); + record_beneath_to_resume (record_beneath_to_resume_ops, + ptid, step, signal); + record_resume_step = 0; + } + else + record_beneath_to_resume (record_beneath_to_resume_ops, ptid, 1, + signal); } } @@ -1077,6 +1091,7 @@ record_wait (struct target_ops *ops, /* This is not a single step. */ ptid_t ret; CORE_ADDR tmp_pc; + struct gdbarch *gdbarch = target_thread_architecture (inferior_ptid); while (1) { @@ -1099,6 +1114,9 @@ record_wait (struct target_ops *ops, tmp_pc = regcache_read_pc (regcache); aspace = get_regcache_aspace (regcache); + if (gdbarch_software_single_step_p (gdbarch)) + remove_single_step_breakpoints (); + if (target_stopped_by_watchpoint ()) { /* Always interested in watchpoints. */ @@ -1129,9 +1147,18 @@ record_wait (struct target_ops *ops, break; } - record_beneath_to_resume (record_beneath_to_resume_ops, - ptid, 1, - TARGET_SIGNAL_0); + if (gdbarch_software_single_step_p (gdbarch)) + { + gdbarch_software_single_step (gdbarch, + get_current_frame ()); + record_beneath_to_resume (record_beneath_to_resume_ops, + ptid, 0, + TARGET_SIGNAL_0); + } + else + record_beneath_to_resume (record_beneath_to_resume_ops, + ptid, 1, + TARGET_SIGNAL_0); continue; } }