[testsuite] Unbuffer the output in gdb.base/multi-forks.c
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 83d39799defe6b8a308754e7bad72b65f81d1038..7b610ef28de639ad6c227494edbe87b6823bac86 100644 (file)
@@ -126,6 +126,7 @@ static void create_breakpoints_sal_default (struct gdbarch *,
 
 static void decode_location_default (struct breakpoint *b,
                                     const struct event_location *location,
+                                    struct program_space *search_pspace,
                                     struct symtabs_and_lines *sals);
 
 static void clear_command (char *, int);
@@ -7797,7 +7798,7 @@ create_thread_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
 
   b->enable_state = bp_enabled;
   /* location has to be used or breakpoint_re_set will delete me.  */
-  b->location = new_address_location (b->loc->address);
+  b->location = new_address_location (b->loc->address, NULL, 0);
 
   update_global_location_list_nothrow (UGLL_MAY_INSERT);
 
@@ -9232,7 +9233,8 @@ update_dprintf_commands (char *args, int from_tty,
 
 /* Create a breakpoint with SAL as location.  Use LOCATION
    as a description of the location, and COND_STRING
-   as condition expression.  */
+   as condition expression.  If LOCATION is NULL then create an
+   "address location" from the address in the SAL.  */
 
 static void
 init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
@@ -9368,7 +9370,18 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
   if (location != NULL)
     b->location = location;
   else
-    b->location = new_address_location (b->loc->address);
+    {
+      const char *addr_string = NULL;
+      int addr_string_len = 0;
+
+      if (location != NULL)
+       addr_string = event_location_to_string (location);
+      if (addr_string != NULL)
+       addr_string_len = strlen (addr_string);
+
+      b->location = new_address_location (b->loc->address,
+                                         addr_string, addr_string_len);
+    }
   b->filter = filter;
 }
 
@@ -9545,7 +9558,7 @@ parse_breakpoint_sals (const struct event_location *location,
              && strchr ("+-", address[0]) != NULL
              && address[1] != '['))
        {
-         decode_line_full (location, DECODE_LINE_FUNFIRSTLINE,
+         decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, NULL,
                            get_last_displayed_symtab (),
                            get_last_displayed_line (),
                            canonical, NULL, NULL);
@@ -9553,7 +9566,7 @@ parse_breakpoint_sals (const struct event_location *location,
        }
     }
 
-  decode_line_full (location, DECODE_LINE_FUNFIRSTLINE,
+  decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, NULL,
                    cursal.symtab, cursal.line, canonical, NULL, NULL);
 }
 
@@ -10447,7 +10460,7 @@ break_range_command (char *arg, int from_tty)
      where +14 means 14 lines from the start location.  */
   end_location = string_to_event_location (&arg, current_language);
   make_cleanup_delete_event_location (end_location);
-  decode_line_full (end_location, DECODE_LINE_FUNFIRSTLINE,
+  decode_line_full (end_location, DECODE_LINE_FUNFIRSTLINE, NULL,
                    sal_start.symtab, sal_start.line,
                    &canonical_end, NULL, NULL);
 
@@ -11712,12 +11725,12 @@ until_break_command (char *arg, int from_tty, int anywhere)
   cleanup = make_cleanup_delete_event_location (location);
 
   if (last_displayed_sal_is_valid ())
-    sals = decode_line_1 (location, DECODE_LINE_FUNFIRSTLINE,
+    sals = decode_line_1 (location, DECODE_LINE_FUNFIRSTLINE, NULL,
                          get_last_displayed_symtab (),
                          get_last_displayed_line ());
   else
     sals = decode_line_1 (location, DECODE_LINE_FUNFIRSTLINE,
-                         (struct symtab *) NULL, 0);
+                         NULL, (struct symtab *) NULL, 0);
 
   if (sals.nelts != 1)
     error (_("Couldn't get information on specified line."));
@@ -13018,6 +13031,7 @@ base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch,
 static void
 base_breakpoint_decode_location (struct breakpoint *b,
                                 const struct event_location *location,
+                                struct program_space *search_pspace,
                                 struct symtabs_and_lines *sals)
 {
   internal_error_pure_virtual_called ();
@@ -13267,9 +13281,10 @@ bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
 static void
 bkpt_decode_location (struct breakpoint *b,
                      const struct event_location *location,
+                     struct program_space *search_pspace,
                      struct symtabs_and_lines *sals)
 {
-  decode_location_default (b, location, sals);
+  decode_location_default (b, location, search_pspace, sals);
 }
 
 /* Virtual table for internal breakpoints.  */
@@ -13453,7 +13468,7 @@ bkpt_probe_create_sals_from_location (const struct event_location *location,
 {
   struct linespec_sals lsal;
 
-  lsal.sals = parse_probes (location, canonical);
+  lsal.sals = parse_probes (location, NULL, canonical);
   lsal.canonical = xstrdup (event_location_to_string (canonical->location));
   VEC_safe_push (linespec_sals, canonical->sals, &lsal);
 }
@@ -13461,9 +13476,10 @@ bkpt_probe_create_sals_from_location (const struct event_location *location,
 static void
 bkpt_probe_decode_location (struct breakpoint *b,
                            const struct event_location *location,
+                           struct program_space *search_pspace,
                            struct symtabs_and_lines *sals)
 {
-  *sals = parse_probes (location, NULL);
+  *sals = parse_probes (location, search_pspace, NULL);
   if (!sals->sals)
     error (_("probe not found"));
 }
@@ -13585,9 +13601,10 @@ tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
 static void
 tracepoint_decode_location (struct breakpoint *b,
                            const struct event_location *location,
+                           struct program_space *search_pspace,
                            struct symtabs_and_lines *sals)
 {
-  decode_location_default (b, location, sals);
+  decode_location_default (b, location, search_pspace, sals);
 }
 
 struct breakpoint_ops tracepoint_breakpoint_ops;
@@ -13608,10 +13625,11 @@ tracepoint_probe_create_sals_from_location
 static void
 tracepoint_probe_decode_location (struct breakpoint *b,
                                  const struct event_location *location,
+                                 struct program_space *search_pspace,
                                  struct symtabs_and_lines *sals)
 {
   /* We use the same method for breakpoint on probes.  */
-  bkpt_probe_decode_location (b, location, sals);
+  bkpt_probe_decode_location (b, location, search_pspace, sals);
 }
 
 static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
@@ -13776,6 +13794,7 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
 static void
 strace_marker_decode_location (struct breakpoint *b,
                               const struct event_location *location,
+                              struct program_space *search_pspace,
                               struct symtabs_and_lines *sals)
 {
   struct tracepoint *tp = (struct tracepoint *) b;
@@ -13993,11 +14012,19 @@ delete_command (char *arg, int from_tty)
     map_breakpoint_numbers (arg, do_map_delete_breakpoint, NULL);
 }
 
+/* Return true if all locations of B bound to PSPACE are pending.  If
+   PSPACE is NULL, all locations of all program spaces are
+   considered.  */
+
 static int
-all_locations_are_pending (struct bp_location *loc)
+all_locations_are_pending (struct breakpoint *b, struct program_space *pspace)
 {
-  for (; loc; loc = loc->next)
-    if (!loc->shlib_disabled
+  struct bp_location *loc;
+
+  for (loc = b->loc; loc != NULL; loc = loc->next)
+    if ((pspace == NULL
+        || loc->pspace == pspace)
+       && !loc->shlib_disabled
        && !loc->pspace->executing_startup)
       return 0;
   return 1;
@@ -14202,17 +14229,58 @@ locations_are_equal (struct bp_location *a, struct bp_location *b)
   return 1;
 }
 
-/* Create new breakpoint locations for B (a hardware or software breakpoint)
-   based on SALS and SALS_END.  If SALS_END.NELTS is not zero, then B is
-   a ranged breakpoint.  */
+/* Split all locations of B that are bound to PSPACE out of B's
+   location list to a separate list and return that list's head.  If
+   PSPACE is NULL, hoist out all locations of B.  */
+
+static struct bp_location *
+hoist_existing_locations (struct breakpoint *b, struct program_space *pspace)
+{
+  struct bp_location head;
+  struct bp_location *i = b->loc;
+  struct bp_location **i_link = &b->loc;
+  struct bp_location *hoisted = &head;
+
+  if (pspace == NULL)
+    {
+      i = b->loc;
+      b->loc = NULL;
+      return i;
+    }
+
+  head.next = NULL;
+
+  while (i != NULL)
+    {
+      if (i->pspace == pspace)
+       {
+         *i_link = i->next;
+         i->next = NULL;
+         hoisted->next = i;
+         hoisted = i;
+       }
+      else
+       i_link = &i->next;
+      i = *i_link;
+    }
+
+  return head.next;
+}
+
+/* Create new breakpoint locations for B (a hardware or software
+   breakpoint) based on SALS and SALS_END.  If SALS_END.NELTS is not
+   zero, then B is a ranged breakpoint.  Only recreates locations for
+   FILTER_PSPACE.  Locations of other program spaces are left
+   untouched.  */
 
 void
 update_breakpoint_locations (struct breakpoint *b,
+                            struct program_space *filter_pspace,
                             struct symtabs_and_lines sals,
                             struct symtabs_and_lines sals_end)
 {
   int i;
-  struct bp_location *existing_locations = b->loc;
+  struct bp_location *existing_locations;
 
   if (sals_end.nelts != 0 && (sals.nelts != 1 || sals_end.nelts != 1))
     {
@@ -14232,10 +14300,10 @@ update_breakpoint_locations (struct breakpoint *b,
      We'd like to retain the location, so that when the library is
      loaded again, we don't loose the enabled/disabled status of the
      individual locations.  */
-  if (all_locations_are_pending (existing_locations) && sals.nelts == 0)
+  if (all_locations_are_pending (b, filter_pspace) && sals.nelts == 0)
     return;
 
-  b->loc = NULL;
+  existing_locations = hoist_existing_locations (b, filter_pspace);
 
   for (i = 0; i < sals.nelts; ++i)
     {
@@ -14326,7 +14394,7 @@ update_breakpoint_locations (struct breakpoint *b,
 
 static struct symtabs_and_lines
 location_to_sals (struct breakpoint *b, struct event_location *location,
-                 int *found)
+                 struct program_space *search_pspace, int *found)
 {
   struct symtabs_and_lines sals = {0};
   struct gdb_exception exception = exception_none;
@@ -14335,7 +14403,7 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
 
   TRY
     {
-      b->ops->decode_location (b, location, &sals);
+      b->ops->decode_location (b, location, search_pspace, &sals);
     }
   CATCH (e, RETURN_MASK_ERROR)
     {
@@ -14351,7 +14419,10 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
         breakpoint being disabled, and don't want to see more
         errors.  */
       if (e.error == NOT_FOUND_ERROR
-         && (b->condition_not_parsed 
+         && (b->condition_not_parsed
+             || (b->loc != NULL
+                 && search_pspace != NULL
+                 && b->loc->pspace != search_pspace)
              || (b->loc && b->loc->shlib_disabled)
              || (b->loc && b->loc->pspace->executing_startup)
              || b->enable_state == bp_disabled))
@@ -14420,8 +14491,9 @@ breakpoint_re_set_default (struct breakpoint *b)
   struct symtabs_and_lines sals, sals_end;
   struct symtabs_and_lines expanded = {0};
   struct symtabs_and_lines expanded_end = {0};
+  struct program_space *filter_pspace = current_program_space;
 
-  sals = location_to_sals (b, b->location, &found);
+  sals = location_to_sals (b, b->location, filter_pspace, &found);
   if (found)
     {
       make_cleanup (xfree, sals.sals);
@@ -14430,7 +14502,8 @@ breakpoint_re_set_default (struct breakpoint *b)
 
   if (b->location_range_end != NULL)
     {
-      sals_end = location_to_sals (b, b->location_range_end, &found);
+      sals_end = location_to_sals (b, b->location_range_end,
+                                  filter_pspace, &found);
       if (found)
        {
          make_cleanup (xfree, sals_end.sals);
@@ -14438,7 +14511,7 @@ breakpoint_re_set_default (struct breakpoint *b)
        }
     }
 
-  update_breakpoint_locations (b, expanded, expanded_end);
+  update_breakpoint_locations (b, filter_pspace, expanded, expanded_end);
 }
 
 /* Default method for creating SALs from an address string.  It basically
@@ -14482,12 +14555,13 @@ create_breakpoints_sal_default (struct gdbarch *gdbarch,
 static void
 decode_location_default (struct breakpoint *b,
                         const struct event_location *location,
+                        struct program_space *search_pspace,
                         struct symtabs_and_lines *sals)
 {
   struct linespec_result canonical;
 
   init_linespec_result (&canonical);
-  decode_line_full (location, DECODE_LINE_FUNFIRSTLINE,
+  decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, search_pspace,
                    (struct symtab *) NULL, 0,
                    &canonical, multiple_symbols_all,
                    b->filter);
@@ -14514,15 +14588,10 @@ decode_location_default (struct breakpoint *b,
 static struct cleanup *
 prepare_re_set_context (struct breakpoint *b)
 {
-  struct cleanup *cleanups;
-
   input_radix = b->input_radix;
-  cleanups = save_current_space_and_thread ();
-  if (b->pspace != NULL)
-    switch_to_program_space_and_thread (b->pspace);
   set_language (b->language);
 
-  return cleanups;
+  return make_cleanup (null_cleanup, NULL);
 }
 
 /* Reset a breakpoint given it's struct breakpoint * BINT.
@@ -14542,7 +14611,9 @@ breakpoint_re_set_one (void *bint)
   return 0;
 }
 
-/* Re-set all breakpoints after symbols have been re-loaded.  */
+/* Re-set breakpoint locations for the current program space.
+   Locations bound to other program spaces are left untouched.  */
+
 void
 breakpoint_re_set (void)
 {
@@ -14553,7 +14624,7 @@ breakpoint_re_set (void)
 
   save_language = current_language->la_language;
   save_input_radix = input_radix;
-  old_chain = save_current_program_space ();
+  old_chain = save_current_space_and_thread ();
 
   ALL_BREAKPOINTS_SAFE (b, b_tmp)
   {
This page took 0.029955 seconds and 4 git commands to generate.