aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog6
-rw-r--r--gdb/breakpoint.c21
-rw-r--r--gdb/infrun.c19
3 files changed, 46 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 3825617..44d8c63 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2000-03-28 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ breakpoint.c, breakpoint.h (remove_hw_watchpoints): New function.
+ infrun.c (resume): Remove hardware watchpoints before stepping
+ when CANNOT_STEP_HW_WATCHPOINTS is nonzero.
+
2000-03-28 Michael Snyder <msnyder@cleaver.cygnus.com>
* Makefile.in: anchor tui-file.h dependency to $srcdir.
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index c5ebf64..768a67f 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -1096,6 +1096,27 @@ remove_breakpoints ()
}
int
+remove_hw_watchpoints ()
+{
+ register struct breakpoint *b;
+ int val;
+
+ ALL_BREAKPOINTS (b)
+ {
+ if (b->inserted
+ && (b->type == bp_hardware_watchpoint
+ || b->type == bp_read_watchpoint
+ || b->type == bp_access_watchpoint))
+ {
+ val = remove_breakpoint (b, mark_uninserted);
+ if (val != 0)
+ return val;
+ }
+ }
+ return 0;
+}
+
+int
reattach_breakpoints (pid)
int pid;
{
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 96a659e..6bc32d8 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -296,6 +296,13 @@ a command like `return' or `jump' to continue execution.\n");
#define HAVE_CONTINUABLE_WATCHPOINT 1
#endif
+#ifndef CANNOT_STEP_HW_WATCHPOINTS
+#define CANNOT_STEP_HW_WATCHPOINTS 0
+#else
+#undef CANNOT_STEP_HW_WATCHPOINTS
+#define CANNOT_STEP_HW_WATCHPOINTS 1
+#endif
+
/* Tables of how to react to signals; the user sets them. */
static unsigned char *signal_stop;
@@ -796,6 +803,18 @@ resume (int step, enum target_signal sig)
step = 0;
#endif
+ /* Some targets (e.g. Solaris x86) have a kernel bug when stepping
+ over an instruction that causes a page fault without triggering
+ a hardware watchpoint. The kernel properly notices that it shouldn't
+ stop, because the hardware watchpoint is not triggered, but it forgets
+ the step request and continues the program normally.
+ Work around the problem by removing hardware watchpoints if a step is
+ requested, GDB will check for a hardware watchpoint trigger after the
+ step anyway. */
+ if (CANNOT_STEP_HW_WATCHPOINTS && step && breakpoints_inserted)
+ remove_hw_watchpoints ();
+
+
/* Normally, by the time we reach `resume', the breakpoints are either
removed or inserted, as appropriate. The exception is if we're sitting
at a permanent breakpoint; we need to step over it, but permanent