* event-loop.c: Include unistd.h if it exists.
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 1c30f6dcf06fd4f37881405d588f9b56e759efa0..47a10f68861cc21fa494eb5bd0dab594168535bd 100644 (file)
@@ -985,6 +985,24 @@ fetch_watchpoint_value (struct expression *exp, struct value **valp,
     }
 }
 
+/* Assuming that B is a watchpoint: returns true if the current thread
+   and its running state are safe to evaluate or update watchpoint B.
+   Watchpoints on local expressions need to be evaluated in the
+   context of the thread that was current when the watchpoint was
+   created, and, that thread needs to be stopped to be able to select
+   the correct frame context.  Watchpoints on global expressions can
+   be evaluated on any thread, and in any state.  It is presently left
+   to the target allowing memory accesses when threads are
+   running.  */
+
+static int
+watchpoint_in_thread_scope (struct breakpoint *b)
+{
+  return (ptid_equal (b->watchpoint_thread, null_ptid)
+         || (ptid_equal (inferior_ptid, b->watchpoint_thread)
+             && !is_executing (inferior_ptid)));
+}
+
 /* Assuming that B is a watchpoint:
    - Reparse watchpoint expression, if REPARSE is non-zero
    - Evaluate expression and store the result in B->val
@@ -993,7 +1011,46 @@ fetch_watchpoint_value (struct expression *exp, struct value **valp,
    - Update the list of values that must be watched in B->loc.
 
    If the watchpoint disposition is disp_del_at_next_stop, then do nothing.
-   If this is local watchpoint that is out of scope, delete it.  */
+   If this is local watchpoint that is out of scope, delete it.
+
+   Even with `set breakpoint always-inserted on' the watchpoints are removed
+   + inserted on each stop here.  Normal breakpoints must never be removed
+   because they might be missed by a running thread when debugging in non-stop
+   mode.  On the other hand, hardware watchpoints (is_hardware_watchpoint;
+   processed here) are specific to each LWP since they are stored in each LWP's
+   hardware debug registers.  Therefore, such LWP must be stopped first in
+   order to be able to modify its hardware watchpoints.
+
+   Hardware watchpoints must be reset exactly once after being presented to the
+   user.  It cannot be done sooner, because it would reset the data used to
+   present the watchpoint hit to the user.  And it must not be done later
+   because it could display the same single watchpoint hit during multiple GDB
+   stops.  Note that the latter is relevant only to the hardware watchpoint
+   types bp_read_watchpoint and bp_access_watchpoint.  False hit by
+   bp_hardware_watchpoint is not user-visible - its hit is suppressed if the
+   memory content has not changed.
+
+   The following constraints influence the location where we can reset hardware
+   watchpoints:
+
+   * target_stopped_by_watchpoint and target_stopped_data_address are called
+     several times when GDB stops.
+
+   [linux]
+   * Multiple hardware watchpoints can be hit at the same time, causing GDB to
+     stop.  GDB only presents one hardware watchpoint hit at a time as the
+     reason for stopping, and all the other hits are presented later, one after
+     the other, each time the user requests the execution to be resumed.
+     Execution is not resumed for the threads still having pending hit event
+     stored in LWP_INFO->STATUS.  While the watchpoint is already removed from
+     the inferior on the first stop the thread hit event is kept being reported
+     from its cached value by linux_nat_stopped_data_address until the real
+     thread resume happens after the watchpoint gets presented and thus its
+     LWP_INFO->STATUS gets reset.
+
+   Therefore the hardware watchpoint hit can get safely reset on the watchpoint
+   removal from inferior.  */
+
 static void
 update_watchpoint (struct breakpoint *b, int reparse)
 {
@@ -1002,7 +1059,12 @@ update_watchpoint (struct breakpoint *b, int reparse)
   struct bp_location *loc;
   int frame_saved;
   bpstat bs;
-  struct program_space *frame_pspace;
+
+  /* If this is a local watchpoint, we only want to check if the
+     watchpoint frame is in scope if the current thread is the thread
+     that was used to create the watchpoint.  */
+  if (!watchpoint_in_thread_scope (b))
+    return;
 
   /* We don't free locations.  They are stored in bp_location array and
      update_global_locations will eventually delete them and remove
@@ -1035,8 +1097,6 @@ update_watchpoint (struct breakpoint *b, int reparse)
        select_frame (fi);
     }
 
-  frame_pspace = get_frame_program_space (get_selected_frame (NULL));
-
   if (within_current_scope && reparse)
     {
       char *s;
@@ -1061,9 +1121,16 @@ update_watchpoint (struct breakpoint *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 (within_current_scope && b->exp)
+  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.  */
+    }
+  else if (within_current_scope && b->exp)
     {
       struct value *val_chain, *v, *result, *next;
+      struct program_space *frame_pspace;
 
       fetch_watchpoint_value (b->exp, &v, &result, &val_chain);
 
@@ -1102,6 +1169,8 @@ update_watchpoint (struct breakpoint *b, int reparse)
              }
          }
 
+      frame_pspace = get_frame_program_space (get_selected_frame (NULL));
+
       /* Look at each value on the value chain.  */
       for (v = val_chain; v; v = next)
        {
@@ -2311,6 +2380,38 @@ software_breakpoint_inserted_here_p (struct address_space *aspace, CORE_ADDR pc)
   return 0;
 }
 
+int
+hardware_watchpoint_inserted_in_range (struct address_space *aspace,
+                                      CORE_ADDR addr, ULONGEST len)
+{
+  struct breakpoint *bpt;
+
+  ALL_BREAKPOINTS (bpt)
+    {
+      struct bp_location *loc;
+
+      if (bpt->type != bp_hardware_watchpoint
+         && bpt->type != bp_access_watchpoint)
+       continue;
+
+      if (!breakpoint_enabled (bpt))
+       continue;
+
+      for (loc = bpt->loc; loc; loc = loc->next)
+       if (loc->pspace->aspace == aspace && loc->inserted)
+         {
+           CORE_ADDR l, h;
+
+           /* Check for intersection.  */
+           l = max (loc->address, addr);
+           h = min (loc->address + loc->length, addr + len);
+           if (l < h)
+             return 1;
+         }
+    }
+  return 0;
+}
+
 /* breakpoint_thread_match (PC, PTID) returns true if the breakpoint at
    PC is valid for process/thread PTID.  */
 
@@ -3085,6 +3186,12 @@ watchpoint_check (void *p)
 
   b = bs->breakpoint_at->owner;
 
+  /* If this is a local watchpoint, we only want to check if the
+     watchpoint frame is in scope if the current thread is the thread
+     that was used to create the watchpoint.  */
+  if (!watchpoint_in_thread_scope (b))
+    return WP_VALUE_NOT_CHANGED;
+
   if (b->exp_valid_block == NULL)
     within_current_scope = 1;
   else
@@ -3199,6 +3306,11 @@ bpstat_check_location (const struct bp_location *bl,
 {
   struct breakpoint *b = bl->owner;
 
+  /* By definition, the inferior does not report stops at
+     tracepoints.  */
+  if (b->type == bp_tracepoint)
+    return 0;
+
   if (b->type != bp_watchpoint
       && b->type != bp_hardware_watchpoint
       && b->type != bp_read_watchpoint
@@ -3546,22 +3658,17 @@ bpstat_stop_status (struct address_space *aspace,
     for (bs = root_bs->next; bs != NULL; bs = bs->next)
       if (!bs->stop
          && bs->breakpoint_at->owner
-         && (bs->breakpoint_at->owner->type == bp_hardware_watchpoint
-             || bs->breakpoint_at->owner->type == bp_read_watchpoint
-             || bs->breakpoint_at->owner->type == bp_access_watchpoint))
+         && is_hardware_watchpoint (bs->breakpoint_at->owner))
        {
-         /* remove/insert can invalidate bs->breakpoint_at, if this
-            location is no longer used by the watchpoint.  Prevent
-            further code from trying to use it.  */
+         update_watchpoint (bs->breakpoint_at->owner, 0 /* don't reparse. */);
+         /* Updating watchpoints invalidates bs->breakpoint_at.
+            Prevent further code from trying to use it.  */
          bs->breakpoint_at = NULL;
          need_remove_insert = 1;
        }
 
   if (need_remove_insert)
-    {
-      remove_breakpoints ();
-      insert_breakpoints ();
-    }
+    update_global_location_list (1);
 
   return root_bs->next;
 }
@@ -4541,21 +4648,28 @@ set_default_breakpoint (int valid, struct program_space *pspace,
    these types to be a duplicate of an actual breakpoint at address zero:
 
       bp_watchpoint
-      bp_hardware_watchpoint
-      bp_read_watchpoint
-      bp_access_watchpoint
-      bp_catchpoint */
+      bp_catchpoint
+
+*/
 
 static int
 breakpoint_address_is_meaningful (struct breakpoint *bpt)
 {
   enum bptype type = bpt->type;
 
-  return (type != bp_watchpoint
-         && type != bp_hardware_watchpoint
-         && type != bp_read_watchpoint
-         && type != bp_access_watchpoint
-         && type != bp_catchpoint);
+  return (type != bp_watchpoint && type != bp_catchpoint);
+}
+
+/* Assuming LOC1 and LOC2's owners are hardware watchpoints, returns
+   true if LOC1 and LOC2 represent the same watchpoint location.  */
+
+static int
+watchpoint_locations_match (struct bp_location *loc1, struct bp_location *loc2)
+{
+  return (loc1->owner->type == loc2->owner->type
+         && loc1->pspace->aspace == loc2->pspace->aspace
+         && loc1->address == loc2->address
+         && loc1->length == loc2->length);
 }
 
 /* Returns true if {ASPACE1,ADDR1} and {ASPACE2,ADDR2} represent the
@@ -4572,6 +4686,25 @@ breakpoint_address_match (struct address_space *aspace1, CORE_ADDR addr1,
          && addr1 == addr2);
 }
 
+/* Assuming LOC1 and LOC2's types' have meaningful target addresses
+   (breakpoint_address_is_meaningful), returns true if LOC1 and LOC2
+   represent the same location.  */
+
+static int
+breakpoint_locations_match (struct bp_location *loc1, struct bp_location *loc2)
+{
+  int hw_point1 = is_hardware_watchpoint (loc1->owner);
+  int hw_point2 = is_hardware_watchpoint (loc2->owner);
+
+  if (hw_point1 != hw_point2)
+    return 0;
+  else if (hw_point1)
+    return watchpoint_locations_match (loc1, loc2);
+  else
+    return breakpoint_address_match (loc1->pspace->aspace, loc1->address,
+                                    loc2->pspace->aspace, loc2->address);
+}
+
 static void
 breakpoint_adjustment_warning (CORE_ADDR from_addr, CORE_ADDR to_addr,
                                int bnum, int have_bnum)
@@ -6212,13 +6345,14 @@ expand_line_sal_maybe (struct symtab_and_line sal)
 
   if (expanded.nelts == 1)
     {
-      /* We had one sal, we got one sal.  Without futher
-        processing, just return the original sal.  */
+      /* We had one sal, we got one sal.  Return that sal, adjusting it
+         past the function prologue if necessary.  */
       xfree (expanded.sals);
       expanded.nelts = 1;
       expanded.sals = xmalloc (sizeof (struct symtab_and_line));
       sal.pc = original_pc;
       expanded.sals[0] = sal;
+      skip_prologue_sal (&expanded.sals[0]);
       do_cleanups (old_chain);
       return expanded;      
     }
@@ -6507,7 +6641,7 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
          if (tok == tmptok)
            error (_("Junk after task keyword."));
          if (!valid_task_id (*task))
-           error (_("Unknown task %d\n"), *task);
+           error (_("Unknown task %d."), *task);
        }
       else
        error (_("Junk at end of arguments."));
@@ -6953,7 +7087,6 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
 {
   struct gdbarch *gdbarch = get_current_arch ();
   struct breakpoint *b, *scope_breakpoint = NULL;
-  struct symtab_and_line sal;
   struct expression *exp;
   struct block *exp_valid_block;
   struct value *val, *mark;
@@ -6964,14 +7097,11 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
   int toklen;
   char *cond_start = NULL;
   char *cond_end = NULL;
-  struct expression *cond = NULL;
   int i, other_type_used, target_resources_ok = 0;
   enum bptype bp_type;
   int mem_cnt = 0;
   int thread = -1;
 
-  init_sal (&sal);             /* initialize to zeroes */
-
   /* Make sure that we actually have parameters to parse.  */
   if (arg != NULL && arg[0] != '\0')
     {
@@ -7033,8 +7163,6 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
         }
     }
 
-  sal.pspace = current_program_space;
-
   /* Parse the rest of the arguments.  */
   innermost_block = NULL;
   exp_start = arg;
@@ -7063,8 +7191,11 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
   toklen = end_tok - tok;
   if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
     {
+      struct expression *cond;
+
       tok = cond_start = end_tok + 1;
       cond = parse_exp_1 (&tok, 0, 0);
+      xfree (cond);
       cond_end = tok;
     }
   if (*tok)
@@ -7134,7 +7265,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
     }
 
   /* Now set up the breakpoint.  */
-  b = set_raw_breakpoint (gdbarch, sal, bp_type);
+  b = set_raw_breakpoint_without_location (NULL, bp_type);
   set_breakpoint_count (breakpoint_count + 1);
   b->number = breakpoint_count;
   b->thread = thread;
@@ -7144,16 +7275,21 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
   b->exp_string = savestring (exp_start, exp_end - exp_start);
   b->val = val;
   b->val_valid = 1;
-  b->loc->cond = cond;
   if (cond_start)
     b->cond_string = savestring (cond_start, cond_end - cond_start);
   else
     b->cond_string = 0;
 
   if (frame)
-    b->watchpoint_frame = get_frame_id (frame);
+    {
+      b->watchpoint_frame = get_frame_id (frame);
+      b->watchpoint_thread = inferior_ptid;
+    }
   else
-    b->watchpoint_frame = null_frame_id;
+    {
+      b->watchpoint_frame = null_frame_id;
+      b->watchpoint_thread = null_ptid;
+    }
 
   if (scope_breakpoint != NULL)
     {
@@ -7164,6 +7300,11 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
     }
 
   value_free_to_mark (mark);
+
+  /* Finally update the new watchpoint.  This creates the locations
+     that should be inserted.  */
+  update_watchpoint (b, 1);
+
   mention (b);
   update_global_location_list (1);
 }
@@ -8073,15 +8214,17 @@ breakpoint_auto_delete (bpstat bs)
   }
 }
 
-/* A comparison function for bp_location A and B being interfaced to qsort.
+/* A comparison function for bp_location AP and BP being interfaced to qsort.
    Sort elements primarily by their ADDRESS (no matter what does
    breakpoint_address_is_meaningful say for its OWNER), secondarily by ordering
    first bp_permanent OWNERed elements and terciarily just ensuring the array
    is sorted stable way despite qsort being an instable algorithm.  */
 
 static int
-bp_location_compare (struct bp_location *a, struct bp_location *b)
+bp_location_compare (const void *ap, const void *bp)
 {
+  struct bp_location *a = *(void **) ap;
+  struct bp_location *b = *(void **) bp;
   int a_perm = a->owner->enable_state == bp_permanent;
   int b_perm = b->owner->enable_state == bp_permanent;
 
@@ -8102,17 +8245,6 @@ bp_location_compare (struct bp_location *a, struct bp_location *b)
   return (a > b) - (a < b);
 }
 
-/* Interface bp_location_compare as the COMPAR parameter of qsort function.  */
-
-static int
-bp_location_compare_for_qsort (const void *ap, const void *bp)
-{
-  struct bp_location *a = *(void **) ap;
-  struct bp_location *b = *(void **) bp;
-
-  return bp_location_compare (a, b);
-}
-
 /* Set bp_location_placed_address_before_address_max and
    bp_location_shadow_len_after_address_max according to the current content of
    the bp_location array.  */
@@ -8171,9 +8303,16 @@ update_global_location_list (int should_insert)
   struct bp_location **locp, *loc;
   struct cleanup *cleanups;
 
-  /* The first bp_location being the only one non-DUPLICATE for the current run
-     of the same ADDRESS.  */
-  struct bp_location *loc_first;
+  /* Used in the duplicates detection below.  When iterating over all
+     bp_locations, points to the first bp_location of a given address.
+     Breakpoints and watchpoints of different types are never
+     duplicates of each other.  Keep one pointer for each type of
+     breakpoint/watchpoint, so we only need to loop over all locations
+     once.  */
+  struct bp_location *bp_loc_first;  /* breakpoint */
+  struct bp_location *wp_loc_first;  /* hardware watchpoint */
+  struct bp_location *awp_loc_first; /* access watchpoint */
+  struct bp_location *rwp_loc_first; /* read watchpoint */
 
   /* Saved former bp_location array which we compare against the newly built
      bp_location from the current state of ALL_BREAKPOINTS.  */
@@ -8196,7 +8335,7 @@ update_global_location_list (int should_insert)
     for (loc = b->loc; loc; loc = loc->next)
       *locp++ = loc;
   qsort (bp_location, bp_location_count, sizeof (*bp_location),
-        bp_location_compare_for_qsort);
+        bp_location_compare);
 
   bp_location_target_extensions_update ();
 
@@ -8272,10 +8411,7 @@ update_global_location_list (int should_insert)
                    {
                      struct bp_location *loc2 = *loc2p;
 
-                     if (breakpoint_address_match (loc2->pspace->aspace,
-                                                   loc2->address,
-                                                   old_loc->pspace->aspace,
-                                                   old_loc->address))
+                     if (breakpoint_locations_match (loc2, old_loc))
                        {
                          /* For the sake of should_be_inserted.
                             Duplicates check below will fix up this later.  */
@@ -8372,17 +8508,24 @@ update_global_location_list (int should_insert)
        }
     }
 
-  /* Rescan breakpoints at the same address and section,
-     marking the first one as "first" and any others as "duplicates".
-     This is so that the bpt instruction is only inserted once.
-     If we have a permanent breakpoint at the same place as BPT, make
-     that one the official one, and the rest as duplicates.  Permanent
-     breakpoints are sorted first for the same address.  */
+  /* Rescan breakpoints at the same address and section, marking the
+     first one as "first" and any others as "duplicates".  This is so
+     that the bpt instruction is only inserted once.  If we have a
+     permanent breakpoint at the same place as BPT, make that one the
+     official one, and the rest as duplicates.  Permanent breakpoints
+     are sorted first for the same address.
 
-  loc_first = NULL;
+     Do the same for hardware watchpoints, but also considering the
+     watchpoint's type (regular/access/read) and length.  */
+
+  bp_loc_first = NULL;
+  wp_loc_first = NULL;
+  awp_loc_first = NULL;
+  rwp_loc_first = NULL;
   ALL_BP_LOCATIONS (loc, locp)
     {
       struct breakpoint *b = loc->owner;
+      struct bp_location **loc_first_p;
 
       if (b->enable_state == bp_disabled
          || b->enable_state == bp_call_disabled
@@ -8398,21 +8541,28 @@ update_global_location_list (int should_insert)
                        _("allegedly permanent breakpoint is not "
                        "actually inserted"));
 
-      if (loc_first == NULL
-         || (overlay_debugging && loc->section != loc_first->section)
-         || !breakpoint_address_match (loc->pspace->aspace, loc->address,
-                                       loc_first->pspace->aspace,
-                                       loc_first->address))
+      if (b->type == bp_hardware_watchpoint)
+       loc_first_p = &wp_loc_first;
+      else if (b->type == bp_read_watchpoint)
+       loc_first_p = &rwp_loc_first;
+      else if (b->type == bp_access_watchpoint)
+       loc_first_p = &awp_loc_first;
+      else
+       loc_first_p = &bp_loc_first;
+
+      if (*loc_first_p == NULL
+         || (overlay_debugging && loc->section != (*loc_first_p)->section)
+         || !breakpoint_locations_match (loc, *loc_first_p))
        {
-         loc_first = loc;
+         *loc_first_p = loc;
          loc->duplicate = 0;
          continue;
        }
 
       loc->duplicate = 1;
 
-      if (loc_first->owner->enable_state == bp_permanent && loc->inserted
-          && b->enable_state != bp_permanent)
+      if ((*loc_first_p)->owner->enable_state == bp_permanent && loc->inserted
+         && b->enable_state != bp_permanent)
        internal_error (__FILE__, __LINE__,
                        _("another breakpoint was inserted on top of "
                        "a permanent breakpoint"));
@@ -9345,6 +9495,35 @@ show_breakpoint_cmd (char *args, int from_tty)
 {
 }
 
+/* Invalidate last known value of any hardware watchpoint if
+   the memory which that value represents has been written to by
+   GDB itself.  */
+
+static void
+invalidate_bp_value_on_memory_change (CORE_ADDR addr, int len,
+                                     const bfd_byte *data)
+{
+  struct breakpoint *bp;
+
+  ALL_BREAKPOINTS (bp)
+    if (bp->enable_state == bp_enabled
+       && bp->type == bp_hardware_watchpoint
+       && bp->val_valid && bp->val)
+      {
+       struct bp_location *loc;
+
+       for (loc = bp->loc; loc != NULL; loc = loc->next)
+         if (loc->loc_type == bp_loc_hardware_watchpoint
+             && loc->address + loc->length > addr
+             && addr + len > loc->address)
+           {
+             value_free (bp->val);
+             bp->val = NULL;
+             bp->val_valid = 0;
+           }
+      }
+}
+
 /* Use default_breakpoint_'s, or nothing if they aren't valid.  */
 
 struct symtabs_and_lines
@@ -9932,6 +10111,7 @@ _initialize_breakpoint (void)
 
   observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
   observer_attach_inferior_exit (clear_syscall_counts);
+  observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
 
   breakpoint_chain = 0;
   /* Don't bother to call set_breakpoint_count.  $bpnum isn't useful
This page took 0.034754 seconds and 4 git commands to generate.