sys/types.h cleanup
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 5ce50defc11076d70f633e155427fd26db60ef09..897b664e8723185ab7c93d3e63fc947a772d806c 100644 (file)
@@ -35,7 +35,7 @@
 #include "gdbthread.h"
 #include "target.h"
 #include "language.h"
-#include "gdb_string.h"
+#include <string.h>
 #include "gdb-demangle.h"
 #include "filenames.h"
 #include "annotate.h"
@@ -1795,11 +1795,19 @@ update_watchpoint (struct watchpoint *b, int reparse)
      don't try to insert watchpoint.  We don't automatically delete
      such watchpoint, though, since failure to parse expression
      is different from out-of-scope watchpoint.  */
-  if ( !target_has_execution)
+  if (!target_has_execution)
     {
       /* Without execution, memory can't change.  No use to try and
         set watchpoint locations.  The watchpoint will be reset when
         the target gains execution, through breakpoint_re_set.  */
+      if (!can_use_hw_watchpoints)
+       {
+         if (b->base.ops->works_in_software_mode (&b->base))
+           b->base.type = bp_watchpoint;
+         else
+           error (_("Can't set read/access watchpoint when "
+                    "hardware watchpoints are disabled."));
+       }
     }
   else if (within_current_scope && b->exp)
     {
@@ -1939,8 +1947,14 @@ update_watchpoint (struct watchpoint *b, int reparse)
                }
            }
          else if (!b->base.ops->works_in_software_mode (&b->base))
-           error (_("Expression cannot be implemented with "
-                    "read/access watchpoint."));
+           {
+             if (!can_use_hw_watchpoints)
+               error (_("Can't set read/access watchpoint when "
+                        "hardware watchpoints are disabled."));
+             else
+               error (_("Expression cannot be implemented with "
+                        "read/access watchpoint."));
+           }
          else
            b->base.type = bp_watchpoint;
 
@@ -3212,8 +3226,6 @@ create_longjmp_master_breakpoint (void)
       struct breakpoint_objfile_data *bp_objfile_data;
 
       gdbarch = get_objfile_arch (objfile);
-      if (!gdbarch_get_longjmp_target_p (gdbarch))
-       continue;
 
       bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
@@ -3263,6 +3275,9 @@ create_longjmp_master_breakpoint (void)
          continue;
        }
 
+      if (!gdbarch_get_longjmp_target_p (gdbarch))
+       continue;
+
       for (i = 0; i < NUM_LONGJMP_NAMES; i++)
        {
          struct breakpoint *b;
@@ -4207,35 +4222,27 @@ bpstat_find_breakpoint (bpstat bsp, struct breakpoint *breakpoint)
 
 /* See breakpoint.h.  */
 
-enum bpstat_signal_value
+int
 bpstat_explains_signal (bpstat bsp, enum gdb_signal sig)
 {
-  enum bpstat_signal_value result = BPSTAT_SIGNAL_NO;
-
   for (; bsp != NULL; bsp = bsp->next)
     {
-      /* Ensure that, if we ever entered this loop, then we at least
-        return BPSTAT_SIGNAL_HIDE.  */
-      enum bpstat_signal_value newval;
-
       if (bsp->breakpoint_at == NULL)
        {
          /* A moribund location can never explain a signal other than
             GDB_SIGNAL_TRAP.  */
          if (sig == GDB_SIGNAL_TRAP)
-           newval = BPSTAT_SIGNAL_HIDE;
-         else
-           newval = BPSTAT_SIGNAL_NO;
+           return 1;
        }
       else
-       newval = bsp->breakpoint_at->ops->explains_signal (bsp->breakpoint_at,
-                                                          sig);
-
-      if (newval > result)
-       result = newval;
+       {
+         if (bsp->breakpoint_at->ops->explains_signal (bsp->breakpoint_at,
+                                                       sig))
+           return 1;
+       }
     }
 
-  return result;
+  return 0;
 }
 
 /* Put in *NUM the breakpoint number of the first breakpoint we are
@@ -4634,10 +4641,12 @@ bpstat_print (bpstat bs, int kind)
   return PRINT_UNKNOWN;
 }
 
-/* Evaluate the expression EXP and return 1 if value is zero.  This is
-   used inside a catch_errors to evaluate the breakpoint condition.
+/* Evaluate the expression EXP and return 1 if value is zero.
+   This returns the inverse of the condition because it is called
+   from catch_errors which returns 0 if an exception happened, and if an
+   exception happens we want execution to stop.
    The argument is a "struct expression *" that has been cast to a
-   "char *" to make it pass through catch_errors.  */
+   "void *" to make it pass through catch_errors.  */
 
 static int
 breakpoint_cond_eval (void *exp)
@@ -4707,7 +4716,7 @@ watchpoints_triggered (struct target_waitstatus *ws)
            w->watchpoint_triggered = watch_triggered_unknown;
          }
 
-      return stopped_by_watchpoint;
+      return 1;
     }
 
   /* The target could report the data address.  Mark watchpoints
@@ -5084,8 +5093,8 @@ bpstat_check_watchpoint (bpstat bs)
     }
 }
 
-
-/* Check conditions (condition proper, frame, thread and ignore count)
+/* For breakpoints that are currently marked as telling gdb to stop,
+   check conditions (condition proper, frame, thread and ignore count)
    of breakpoint referred to by BS.  If we should not stop for this
    breakpoint, set BS->stop to 0.  */
 
@@ -5095,6 +5104,10 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
   int thread_id = pid_to_thread_id (ptid);
   const struct bp_location *bl;
   struct breakpoint *b;
+  int value_is_zero = 0;
+  struct expression *cond;
+
+  gdb_assert (bs->stop);
 
   /* BS is built for existing struct breakpoint.  */
   bl = bs->bp_location_at;
@@ -5108,109 +5121,110 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
 
   if (frame_id_p (b->frame_id)
       && !frame_id_eq (b->frame_id, get_stack_frame_id (get_current_frame ())))
-    bs->stop = 0;
-  else if (bs->stop)
     {
-      int value_is_zero = 0;
-      struct expression *cond;
+      bs->stop = 0;
+      return;
+    }
 
-      /* Evaluate Python breakpoints that have a "stop"
-        method implemented.  */
-      if (b->py_bp_object)
-       bs->stop = gdbpy_should_stop (b->py_bp_object);
+  /* If this is a thread-specific breakpoint, don't waste cpu evaluating the
+     condition if this isn't the specified thread.  */
+  if (b->thread != -1 && b->thread != thread_id)
+    {
+      bs->stop = 0;
+      return;
+    }
 
-      if (is_watchpoint (b))
-       {
-         struct watchpoint *w = (struct watchpoint *) b;
+  /* Evaluate Python breakpoints that have a "stop" method implemented.  */
+  if (b->py_bp_object)
+    bs->stop = gdbpy_should_stop (b->py_bp_object);
 
-         cond = w->cond_exp;
-       }
+  if (is_watchpoint (b))
+    {
+      struct watchpoint *w = (struct watchpoint *) b;
+
+      cond = w->cond_exp;
+    }
+  else
+    cond = bl->cond;
+
+  if (cond && b->disposition != disp_del_at_next_stop)
+    {
+      int within_current_scope = 1;
+      struct watchpoint * w;
+
+      /* We use value_mark and value_free_to_mark because it could
+        be a long time before we return to the command level and
+        call free_all_values.  We can't call free_all_values
+        because we might be in the middle of evaluating a
+        function call.  */
+      struct value *mark = value_mark ();
+
+      if (is_watchpoint (b))
+       w = (struct watchpoint *) b;
       else
-       cond = bl->cond;
+       w = NULL;
 
-      if (cond && b->disposition != disp_del_at_next_stop)
+      /* Need to select the frame, with all that implies so that
+        the conditions will have the right context.  Because we
+        use the frame, we will not see an inlined function's
+        variables when we arrive at a breakpoint at the start
+        of the inlined function; the current frame will be the
+        call site.  */
+      if (w == NULL || w->cond_exp_valid_block == NULL)
+       select_frame (get_current_frame ());
+      else
        {
-         int within_current_scope = 1;
-         struct watchpoint * w;
-
-         /* We use value_mark and value_free_to_mark because it could
-            be a long time before we return to the command level and
-            call free_all_values.  We can't call free_all_values
-            because we might be in the middle of evaluating a
-            function call.  */
-         struct value *mark = value_mark ();
-
-         if (is_watchpoint (b))
-           w = (struct watchpoint *) b;
-         else
-           w = NULL;
-
-         /* Need to select the frame, with all that implies so that
-            the conditions will have the right context.  Because we
-            use the frame, we will not see an inlined function's
-            variables when we arrive at a breakpoint at the start
-            of the inlined function; the current frame will be the
-            call site.  */
-         if (w == NULL || w->cond_exp_valid_block == NULL)
-           select_frame (get_current_frame ());
-         else
-           {
-             struct frame_info *frame;
-
-             /* For local watchpoint expressions, which particular
-                instance of a local is being watched matters, so we
-                keep track of the frame to evaluate the expression
-                in.  To evaluate the condition however, it doesn't
-                really matter which instantiation of the function
-                where the condition makes sense triggers the
-                watchpoint.  This allows an expression like "watch
-                global if q > 10" set in `func', catch writes to
-                global on all threads that call `func', or catch
-                writes on all recursive calls of `func' by a single
-                thread.  We simply always evaluate the condition in
-                the innermost frame that's executing where it makes
-                sense to evaluate the condition.  It seems
-                intuitive.  */
-             frame = block_innermost_frame (w->cond_exp_valid_block);
-             if (frame != NULL)
-               select_frame (frame);
-             else
-               within_current_scope = 0;
-           }
-         if (within_current_scope)
-           value_is_zero
-             = catch_errors (breakpoint_cond_eval, cond,
-                             "Error in testing breakpoint condition:\n",
-                             RETURN_MASK_ALL);
+         struct frame_info *frame;
+
+         /* For local watchpoint expressions, which particular
+            instance of a local is being watched matters, so we
+            keep track of the frame to evaluate the expression
+            in.  To evaluate the condition however, it doesn't
+            really matter which instantiation of the function
+            where the condition makes sense triggers the
+            watchpoint.  This allows an expression like "watch
+            global if q > 10" set in `func', catch writes to
+            global on all threads that call `func', or catch
+            writes on all recursive calls of `func' by a single
+            thread.  We simply always evaluate the condition in
+            the innermost frame that's executing where it makes
+            sense to evaluate the condition.  It seems
+            intuitive.  */
+         frame = block_innermost_frame (w->cond_exp_valid_block);
+         if (frame != NULL)
+           select_frame (frame);
          else
-           {
-             warning (_("Watchpoint condition cannot be tested "
-                        "in the current scope"));
-             /* If we failed to set the right context for this
-                watchpoint, unconditionally report it.  */
-             value_is_zero = 0;
-           }
-         /* FIXME-someday, should give breakpoint #.  */
-         value_free_to_mark (mark);
+           within_current_scope = 0;
        }
-
-      if (cond && value_is_zero)
+      if (within_current_scope)
+       value_is_zero
+         = catch_errors (breakpoint_cond_eval, cond,
+                         "Error in testing breakpoint condition:\n",
+                         RETURN_MASK_ALL);
+      else
        {
-         bs->stop = 0;
+         warning (_("Watchpoint condition cannot be tested "
+                    "in the current scope"));
+         /* If we failed to set the right context for this
+            watchpoint, unconditionally report it.  */
+         value_is_zero = 0;
        }
-      else if (b->thread != -1 && b->thread != thread_id)
-       {
-         bs->stop = 0;
-       }
-      else if (b->ignore_count > 0)
-       {
-         b->ignore_count--;
-         bs->stop = 0;
-         /* Increase the hit count even though we don't stop.  */
-         ++(b->hit_count);
-         observer_notify_breakpoint_modified (b);
-       }       
+      /* FIXME-someday, should give breakpoint #.  */
+      value_free_to_mark (mark);
     }
+
+  if (cond && value_is_zero)
+    {
+      bs->stop = 0;
+    }
+  else if (b->ignore_count > 0)
+    {
+      b->ignore_count--;
+      bs->stop = 0;
+      /* Increase the hit count even though we don't stop.  */
+      ++(b->hit_count);
+      observer_notify_breakpoint_modified (b);
+    }  
 }
 
 
@@ -7468,9 +7482,9 @@ disable_breakpoints_in_shlibs (void)
   }
 }
 
-/* Disable any breakpoints and tracepoints that are in an unloaded shared
-   library.  Only apply to enabled breakpoints, disabled ones can just stay
-   disabled.  */
+/* Disable any breakpoints and tracepoints that are in SOLIB upon
+   notification of unloaded_shlib.  Only apply to enabled breakpoints,
+   disabled ones can just stay disabled.  */
 
 static void
 disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
@@ -7522,6 +7536,66 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
   }
 }
 
+/* Disable any breakpoints and tracepoints in OBJFILE upon
+   notification of free_objfile.  Only apply to enabled breakpoints,
+   disabled ones can just stay disabled.  */
+
+static void
+disable_breakpoints_in_freed_objfile (struct objfile *objfile)
+{
+  struct breakpoint *b;
+
+  if (objfile == NULL)
+    return;
+
+  /* If the file is a shared library not loaded by the user then
+     solib_unloaded was notified and disable_breakpoints_in_unloaded_shlib
+     was called.  In that case there is no need to take action again.  */
+  if ((objfile->flags & OBJF_SHARED) && !(objfile->flags & OBJF_USERLOADED))
+    return;
+
+  ALL_BREAKPOINTS (b)
+    {
+      struct bp_location *loc;
+      int bp_modified = 0;
+
+      if (!is_breakpoint (b) && !is_tracepoint (b))
+       continue;
+
+      for (loc = b->loc; loc != NULL; loc = loc->next)
+       {
+         CORE_ADDR loc_addr = loc->address;
+
+         if (loc->loc_type != bp_loc_hardware_breakpoint
+             && loc->loc_type != bp_loc_software_breakpoint)
+           continue;
+
+         if (loc->shlib_disabled != 0)
+           continue;
+
+         if (objfile->pspace != loc->pspace)
+           continue;
+
+         if (loc->loc_type != bp_loc_hardware_breakpoint
+             && loc->loc_type != bp_loc_software_breakpoint)
+           continue;
+
+         if (is_addr_in_objfile (loc_addr, objfile))
+           {
+             loc->shlib_disabled = 1;
+             loc->inserted = 0;
+
+             mark_breakpoint_location_modified (loc);
+
+             bp_modified = 1;
+           }
+       }
+
+      if (bp_modified)
+       observer_notify_breakpoint_modified (b);
+    }
+}
+
 /* FORK & VFORK catchpoints.  */
 
 /* An instance of this type is used to represent a fork or vfork
@@ -10689,15 +10763,15 @@ print_recreate_watchpoint (struct breakpoint *b, struct ui_file *fp)
 /* Implement the "explains_signal" breakpoint_ops method for
    watchpoints.  */
 
-static enum bpstat_signal_value
+static int
 explains_signal_watchpoint (struct breakpoint *b, enum gdb_signal sig)
 {
   /* A software watchpoint cannot cause a signal other than
      GDB_SIGNAL_TRAP.  */
   if (b->type == bp_watchpoint && sig != GDB_SIGNAL_TRAP)
-    return BPSTAT_SIGNAL_NO;
+    return 0;
 
-  return BPSTAT_SIGNAL_HIDE;
+  return 1;
 }
 
 /* The breakpoint_ops structure to be used in hardware watchpoints.  */
@@ -11081,13 +11155,6 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   if (*tok)
     error (_("Junk at end of command."));
 
-  if (accessflag == hw_read)
-    bp_type = bp_read_watchpoint;
-  else if (accessflag == hw_access)
-    bp_type = bp_access_watchpoint;
-  else
-    bp_type = bp_hardware_watchpoint;
-
   frame = block_innermost_frame (exp_valid_block);
 
   /* If the expression is "local", then set up a "watchpoint scope"
@@ -11124,7 +11191,17 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
        }
     }
 
-  /* Now set up the breakpoint.  */
+  /* Now set up the breakpoint.  We create all watchpoints as hardware
+     watchpoints here even if hardware watchpoints are turned off, a call
+     to update_watchpoint later in this function will cause the type to
+     drop back to bp_watchpoint (software watchpoint) if required.  */
+
+  if (accessflag == hw_read)
+    bp_type = bp_read_watchpoint;
+  else if (accessflag == hw_access)
+    bp_type = bp_access_watchpoint;
+  else
+    bp_type = bp_hardware_watchpoint;
 
   w = XCNEW (struct watchpoint);
   b = &w->base;
@@ -12802,10 +12879,10 @@ base_breakpoint_decode_linespec (struct breakpoint *b, char **s,
 
 /* The default 'explains_signal' method.  */
 
-static enum bpstat_signal_value
+static int
 base_breakpoint_explains_signal (struct breakpoint *b, enum gdb_signal sig)
 {
-  return BPSTAT_SIGNAL_HIDE;
+  return 1;
 }
 
 /* The default "after_condition_true" method.  */
@@ -15997,6 +16074,7 @@ _initialize_breakpoint (void)
   initialize_breakpoint_ops ();
 
   observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
+  observer_attach_free_objfile (disable_breakpoints_in_freed_objfile);
   observer_attach_inferior_exit (clear_syscall_counts);
   observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
 
This page took 0.032728 seconds and 4 git commands to generate.