2000-03-28 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
authorMichael Snyder <msnyder@vmware.com>
Tue, 28 Mar 2000 22:30:19 +0000 (22:30 +0000)
committerMichael Snyder <msnyder@vmware.com>
Tue, 28 Mar 2000 22:30:19 +0000 (22:30 +0000)
        breakpoint.c, breakpoint.h (remove_hw_watchpoints):  New function.
        infrun.c (resume):  Remove hardware watchpoints before stepping
        when CANNOT_STEP_HW_WATCHPOINTS is nonzero.

gdb/ChangeLog
gdb/breakpoint.c
gdb/infrun.c

index 38256178df8c4e24177822e313c7a3d2d6b65b0f..44d8c63a088e511d531d88c765fe93bedf1b4f8f 100644 (file)
@@ -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.
index c5ebf6460a0362ef522923525b96e3e224b2ba55..768a67f7534dce4987d0e2f9b8c1d54a9c7f5ea0 100644 (file)
@@ -1095,6 +1095,27 @@ remove_breakpoints ()
   return 0;
 }
 
+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;
index 96a659ebf4a2f5d639c5c8ac909626f18ae6868d..6bc32d803beb70310571d76ef9aa07689df07a95 100644 (file)
@@ -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