aboutsummaryrefslogtreecommitdiff
path: root/gdb/breakpoint.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2014-10-15 20:18:30 +0100
committerPedro Alves <palves@redhat.com>2014-10-15 20:18:30 +0100
commit963f9c80cb3f12fb779cf3189072ac48946da96c (patch)
tree527f5d71df8f5e01985f508a01d460a52a831037 /gdb/breakpoint.c
parent6cc83d2a4000e89e4f6f2eb33ffade2d72acfa0f (diff)
downloadgdb-963f9c80cb3f12fb779cf3189072ac48946da96c.zip
gdb-963f9c80cb3f12fb779cf3189072ac48946da96c.tar.gz
gdb-963f9c80cb3f12fb779cf3189072ac48946da96c.tar.bz2
Rewrite non-continuable watchpoints handling
When GDB finds out the target triggered a watchpoint, and the target has non-continuable watchpoints, GDB sets things up to step past the instruction that triggered the watchpoint. This is just like stepping past a breakpoint, but goes through a different mechanism - it resumes only the thread that needs to step past the watchpoint, but also switches a "infwait state" global, that has the effect that the next target_wait only wait for events only from that thread. This forcing of a ptid to pass to target_wait obviously becomes a bottleneck if we ever support stepping past different watchpoints simultaneously (in separate processes). It's also unnecessary -- the target should only return events for threads that have been resumed; if no other thread than the one we're stepping past the watchpoint has been resumed, then those other threads should not report events. If we couldn't assume that, then stepping past regular breakpoints would be broken for not likewise forcing a similar infwait_state. So this patch eliminates infwait_state, and instead teaches keep_going to mark step_over_info in a way that has the breakpoints module skip inserting watchpoints (because we're stepping past one), like it skips breakpoints when we're stepping past one. Tested on: - x86_64 Fedora 20 (continuable watchpoints) - PPC64 Fedora 18 (non-steppable watchpoints) gdb/ 2014-10-15 Pedro Alves <palves@redhat.com> * breakpoint.c (should_be_inserted): Don't insert watchpoints if trying to step past a non-steppable watchpoint. * gdbthread.h (struct thread_info) <stepping_over_watchpoint>: New field. * infrun.c (struct step_over_info): Add new field 'nonsteppable_watchpoint_p' and adjust comments. (set_step_over_info): New 'nonsteppable_watchpoint_p' parameter. Adjust. (clear_step_over_info): Clear nonsteppable_watchpoint_p as well. (stepping_past_nonsteppable_watchpoint): New function. (step_over_info_valid_p): Also return true if stepping past a nonsteppable watchpoint. (proceed): Adjust call to set_step_over_info. Remove reference to init_infwait_state. (init_wait_for_inferior): Remove reference to init_infwait_state. (waiton_ptid): Delete global. (struct execution_control_state) <stepped_after_stopped_by_watchpoint>: Delete field. (wait_for_inferior, fetch_inferior_event): Always pass minus_one_ptid to target_wait. (init_thread_stepping_state): Clear 'stepping_over_watchpoint' field. (init_infwait_state): Delete function. (handle_inferior_event): Remove infwait_state handling. (handle_signal_stop) <watchpoints handling>: Adjust after stepped_after_stopped_by_watchpoint removal. Don't remove breakpoints here nor set infwait_state. Set the thread's stepping_over_watchpoint flag, and call keep_going instead. (keep_going): Handle stepping_over_watchpoint. Adjust set_step_over_info calls. * infrun.h (stepping_past_nonsteppable_watchpoint): Declare function.
Diffstat (limited to 'gdb/breakpoint.c')
-rw-r--r--gdb/breakpoint.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index dc2e297..2a6e51d 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -2208,6 +2208,22 @@ should_be_inserted (struct bp_location *bl)
return 0;
}
+ /* Don't insert watchpoints if we're trying to step past the
+ instruction that triggered one. */
+ if ((bl->loc_type == bp_loc_hardware_watchpoint)
+ && stepping_past_nonsteppable_watchpoint ())
+ {
+ if (debug_infrun)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "infrun: stepping past non-steppable watchpoint. "
+ "skipping watchpoint at %s:%d\n",
+ paddress (bl->gdbarch, bl->address),
+ bl->length);
+ }
+ return 0;
+ }
+
return 1;
}