]> Git Repo - binutils.git/blobdiff - gdb/breakpoint.c
Stop using errno values around target_xfer interfaces and memory errors.
[binutils.git] / gdb / breakpoint.c
index ef9c23c46422063534701a01b0de1cfe210f35bd..f0da90a5ce76364e7355180d69db09c50073d201 100644 (file)
@@ -119,7 +119,6 @@ static void create_sals_from_address_default (char **,
 
 static void create_breakpoints_sal_default (struct gdbarch *,
                                            struct linespec_result *,
-                                           struct linespec_sals *,
                                            char *, char *, enum bptype,
                                            enum bpdisp, int, int,
                                            int,
@@ -301,7 +300,7 @@ struct breakpoint_ops bkpt_breakpoint_ops;
 static struct breakpoint_ops bkpt_probe_breakpoint_ops;
 
 /* Dynamic printf class type.  */
-static struct breakpoint_ops dprintf_breakpoint_ops;
+struct breakpoint_ops dprintf_breakpoint_ops;
 
 /* The style in which to perform a dynamic printf.  This is a user
    option because different output options have different tradeoffs;
@@ -1012,27 +1011,14 @@ condition_completer (struct cmd_list_element *cmd,
       len = strlen (text);
 
       ALL_BREAKPOINTS (b)
-      {
-       int single = b->loc->next == NULL;
-       struct bp_location *loc;
-       int count = 1;
-
-       for (loc = b->loc; loc; loc = loc->next)
-         {
-           char location[50];
-
-           if (single)
-             xsnprintf (location, sizeof (location), "%d", b->number);
-           else
-             xsnprintf (location, sizeof (location),  "%d.%d", b->number,
-                        count);
+       {
+         char number[50];
 
-           if (strncmp (location, text, len) == 0)
-             VEC_safe_push (char_ptr, result, xstrdup (location));
+         xsnprintf (number, sizeof (number), "%d", b->number);
 
-           ++count;
-         }
-      }
+         if (strncmp (number, text, len) == 0)
+           VEC_safe_push (char_ptr, result, xstrdup (number));
+       }
 
       return result;
     }
@@ -1821,7 +1807,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
       struct value *val_chain, *v, *result, *next;
       struct program_space *frame_pspace;
 
-      fetch_subexp_value (b->exp, &pc, &v, &result, &val_chain);
+      fetch_subexp_value (b->exp, &pc, &v, &result, &val_chain, 0);
 
       /* Avoid setting b->val if it's already set.  The meaning of
         b->val is 'the last value' user saw, and we should update
@@ -2261,6 +2247,8 @@ parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
                          fpieces, nargs, argvec);
     }
 
+  do_cleanups (old_cleanups);
+
   if (ex.reason < 0)
     {
       /* If we got here, it means the command could not be parsed to a valid
@@ -2269,8 +2257,6 @@ parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
       return NULL;
     }
 
-  do_cleanups (old_cleanups);
-
   /* We have a valid agent expression, return it.  */
   return aexpr;
 }
@@ -2584,15 +2570,16 @@ insert_bp_location (struct bp_location *bl,
                }
              else
                {
+                 char *message = memory_error_message (TARGET_XFER_E_IO,
+                                                       bl->gdbarch, bl->address);
+                 struct cleanup *old_chain = make_cleanup (xfree, message);
+
                  fprintf_unfiltered (tmp_error_stream, 
-                                     "Cannot insert breakpoint %d.\n", 
-                                     bl->owner->number);
-                 fprintf_filtered (tmp_error_stream, 
-                                   "Error accessing memory address ");
-                 fputs_filtered (paddress (bl->gdbarch, bl->address),
-                                 tmp_error_stream);
-                 fprintf_filtered (tmp_error_stream, ": %s.\n",
-                                   safe_strerror (val));
+                                     "Cannot insert breakpoint %d.\n"
+                                     "%s\n",
+                                     bl->owner->number, message);
+
+                 do_cleanups (old_chain);
                }
 
            }
@@ -2942,6 +2929,30 @@ remove_breakpoints (void)
   return val;
 }
 
+/* When a thread exits, remove breakpoints that are related to
+   that thread.  */
+
+static void
+remove_threaded_breakpoints (struct thread_info *tp, int silent)
+{
+  struct breakpoint *b, *b_tmp;
+
+  ALL_BREAKPOINTS_SAFE (b, b_tmp)
+    {
+      if (b->thread == tp->num && user_breakpoint_p (b))
+       {
+         b->disposition = disp_del_at_next_stop;
+
+         printf_filtered (_("\
+Thread-specific breakpoint %d deleted - thread %d no longer in the thread list.\n"),
+                         b->number, tp->num);
+
+         /* Hide it from the user.  */
+         b->number = 0;
+       }
+    }
+}
+
 /* Remove breakpoints of process PID.  */
 
 int
@@ -3208,8 +3219,23 @@ create_longjmp_master_breakpoint (void)
 
       if (!bp_objfile_data->longjmp_searched)
        {
-         bp_objfile_data->longjmp_probes
-           = find_probes_in_objfile (objfile, "libc", "longjmp");
+         VEC (probe_p) *ret;
+
+         ret = find_probes_in_objfile (objfile, "libc", "longjmp");
+         if (ret != NULL)
+           {
+             /* We are only interested in checking one element.  */
+             struct probe *p = VEC_index (probe_p, ret, 0);
+
+             if (!can_evaluate_probe_arguments (p))
+               {
+                 /* We cannot use the probe interface here, because it does
+                    not know how to evaluate arguments.  */
+                 VEC_free (probe_p, ret);
+                 ret = NULL;
+               }
+           }
+         bp_objfile_data->longjmp_probes = ret;
          bp_objfile_data->longjmp_searched = 1;
        }
 
@@ -3350,8 +3376,24 @@ create_exception_master_breakpoint (void)
       /* We prefer the SystemTap probe point if it exists.  */
       if (!bp_objfile_data->exception_searched)
        {
-         bp_objfile_data->exception_probes
-           = find_probes_in_objfile (objfile, "libgcc", "unwind");
+         VEC (probe_p) *ret;
+
+         ret = find_probes_in_objfile (objfile, "libgcc", "unwind");
+
+         if (ret != NULL)
+           {
+             /* We are only interested in checking one element.  */
+             struct probe *p = VEC_index (probe_p, ret, 0);
+
+             if (!can_evaluate_probe_arguments (p))
+               {
+                 /* We cannot use the probe interface here, because it does
+                    not know how to evaluate arguments.  */
+                 VEC_free (probe_p, ret);
+                 ret = NULL;
+               }
+           }
+         bp_objfile_data->exception_probes = ret;
          bp_objfile_data->exception_searched = 1;
        }
 
@@ -3540,7 +3582,7 @@ detach_breakpoints (ptid_t ptid)
   struct cleanup *old_chain = save_inferior_ptid ();
   struct inferior *inf = current_inferior ();
 
-  if (PIDGET (ptid) == PIDGET (inferior_ptid))
+  if (ptid_get_pid (ptid) == ptid_get_pid (inferior_ptid))
     error (_("Cannot detach breakpoints of inferior_ptid"));
 
   /* Set inferior_ptid; remove_breakpoint_1 uses this global.  */
@@ -3550,6 +3592,15 @@ detach_breakpoints (ptid_t ptid)
     if (bl->pspace != inf->pspace)
       continue;
 
+    /* This function must physically remove breakpoints locations
+       from the specified ptid, without modifying the breakpoint
+       package's state.  Locations of type bp_loc_other are only
+       maintained at GDB side.  So, there is no need to remove
+       these bp_loc_other locations.  Moreover, removing these
+       would modify the breakpoint package's state.  */
+    if (bl->loc_type == bp_loc_other)
+      continue;
+
     if (bl->inserted)
       val |= remove_breakpoint_1 (bl, mark_inserted);
   }
@@ -4157,7 +4208,7 @@ bpstat_find_breakpoint (bpstat bsp, struct breakpoint *breakpoint)
 /* See breakpoint.h.  */
 
 enum bpstat_signal_value
-bpstat_explains_signal (bpstat bsp)
+bpstat_explains_signal (bpstat bsp, enum gdb_signal sig)
 {
   enum bpstat_signal_value result = BPSTAT_SIGNAL_NO;
 
@@ -4165,10 +4216,20 @@ bpstat_explains_signal (bpstat bsp)
     {
       /* Ensure that, if we ever entered this loop, then we at least
         return BPSTAT_SIGNAL_HIDE.  */
-      enum bpstat_signal_value newval = BPSTAT_SIGNAL_HIDE;
+      enum bpstat_signal_value newval;
 
-      if (bsp->breakpoint_at != NULL)
-       newval = bsp->breakpoint_at->ops->explains_signal (bsp->breakpoint_at);
+      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;
+       }
+      else
+       newval = bsp->breakpoint_at->ops->explains_signal (bsp->breakpoint_at,
+                                                          sig);
 
       if (newval > result)
        result = newval;
@@ -4786,7 +4847,7 @@ watchpoint_check (void *p)
        return WP_VALUE_CHANGED;
 
       mark = value_mark ();
-      fetch_subexp_value (b->exp, &pc, &new_val, NULL, NULL);
+      fetch_subexp_value (b->exp, &pc, &new_val, NULL, NULL, 0);
 
       /* We use value_equal_contents instead of value_equal because
         the latter coerces an array to a pointer, thus comparing just
@@ -5303,6 +5364,8 @@ bpstat_stop_status (struct address_space *aspace,
              if (command_line_is_silent (bs->commands
                                          ? bs->commands->commands : NULL))
                bs->print = 0;
+
+             b->ops->after_condition_true (bs);
            }
 
        }
@@ -5356,21 +5419,6 @@ handle_jit_event (void)
   target_terminal_inferior ();
 }
 
-/* Handle an solib event by calling solib_add.  */
-
-void
-handle_solib_event (void)
-{
-  clear_program_space_solib_cache (current_inferior ()->pspace);
-
-  /* Check for any newly added shared libraries if we're supposed to
-     be adding them automatically.  Switch terminal for any messages
-     produced by breakpoint_re_set.  */
-  target_terminal_ours_for_output ();
-  solib_add (NULL, 0, &current_target, auto_solib_add);
-  target_terminal_inferior ();
-}
-
 /* Prepare WHAT final decision for infrun.  */
 
 /* Decide what infrun needs to do with this bpstat.  */
@@ -5807,8 +5855,6 @@ bptype_string (enum bptype type)
   return bptypes[(int) type].description;
 }
 
-DEF_VEC_I(int);
-
 /* For MI, output a field named 'thread-groups' with a list as the value.
    For CLI, prefix the list with the string 'inf'. */
 
@@ -5818,8 +5864,7 @@ output_thread_groups (struct ui_out *uiout,
                      VEC(int) *inf_num,
                      int mi_only)
 {
-  struct cleanup *back_to = make_cleanup_ui_out_list_begin_end (uiout,
-                                                               field_name);
+  struct cleanup *back_to;
   int is_mi = ui_out_is_mi_like_p (uiout);
   int inf;
   int i;
@@ -5829,6 +5874,8 @@ output_thread_groups (struct ui_out *uiout,
   if (!is_mi && mi_only)
     return;
 
+  back_to = make_cleanup_ui_out_list_begin_end (uiout, field_name);
+
   for (i = 0; VEC_iterate (int, inf_num, i, inf); ++i)
     {
       if (is_mi)
@@ -7500,7 +7547,7 @@ struct fork_catchpoint
 static int
 insert_catch_fork (struct bp_location *bl)
 {
-  return target_insert_fork_catchpoint (PIDGET (inferior_ptid));
+  return target_insert_fork_catchpoint (ptid_get_pid (inferior_ptid));
 }
 
 /* Implement the "remove" breakpoint_ops method for fork
@@ -7509,7 +7556,7 @@ insert_catch_fork (struct bp_location *bl)
 static int
 remove_catch_fork (struct bp_location *bl)
 {
-  return target_remove_fork_catchpoint (PIDGET (inferior_ptid));
+  return target_remove_fork_catchpoint (ptid_get_pid (inferior_ptid));
 }
 
 /* Implement the "breakpoint_hit" breakpoint_ops method for fork
@@ -7617,7 +7664,7 @@ static struct breakpoint_ops catch_fork_breakpoint_ops;
 static int
 insert_catch_vfork (struct bp_location *bl)
 {
-  return target_insert_vfork_catchpoint (PIDGET (inferior_ptid));
+  return target_insert_vfork_catchpoint (ptid_get_pid (inferior_ptid));
 }
 
 /* Implement the "remove" breakpoint_ops method for vfork
@@ -7626,7 +7673,7 @@ insert_catch_vfork (struct bp_location *bl)
 static int
 remove_catch_vfork (struct bp_location *bl)
 {
-  return target_remove_vfork_catchpoint (PIDGET (inferior_ptid));
+  return target_remove_vfork_catchpoint (ptid_get_pid (inferior_ptid));
 }
 
 /* Implement the "breakpoint_hit" breakpoint_ops method for vfork
@@ -8119,7 +8166,7 @@ insert_catch_syscall (struct bp_location *bl)
        }
     }
 
-  return target_set_syscall_catchpoint (PIDGET (inferior_ptid),
+  return target_set_syscall_catchpoint (ptid_get_pid (inferior_ptid),
                                        inf_data->total_syscalls_count != 0,
                                        inf_data->any_syscall_count,
                                        VEC_length (int,
@@ -8159,7 +8206,7 @@ remove_catch_syscall (struct bp_location *bl)
         }
     }
 
-  return target_set_syscall_catchpoint (PIDGET (inferior_ptid),
+  return target_set_syscall_catchpoint (ptid_get_pid (inferior_ptid),
                                        inf_data->total_syscalls_count != 0,
                                        inf_data->any_syscall_count,
                                        VEC_length (int,
@@ -8482,13 +8529,13 @@ dtor_catch_exec (struct breakpoint *b)
 static int
 insert_catch_exec (struct bp_location *bl)
 {
-  return target_insert_exec_catchpoint (PIDGET (inferior_ptid));
+  return target_insert_exec_catchpoint (ptid_get_pid (inferior_ptid));
 }
 
 static int
 remove_catch_exec (struct bp_location *bl)
 {
-  return target_remove_exec_catchpoint (PIDGET (inferior_ptid));
+  return target_remove_exec_catchpoint (ptid_get_pid (inferior_ptid));
 }
 
 static int
@@ -8952,25 +8999,16 @@ update_dprintf_command_list (struct breakpoint *b)
                    _("Invalid dprintf style."));
 
   gdb_assert (printf_line != NULL);
-  /* Manufacture a printf/continue sequence.  */
+  /* Manufacture a printf sequence.  */
   {
-    struct command_line *printf_cmd_line, *cont_cmd_line = NULL;
-
-    if (strcmp (dprintf_style, dprintf_style_agent) != 0)
-      {
-       cont_cmd_line = xmalloc (sizeof (struct command_line));
-       cont_cmd_line->control_type = simple_control;
-       cont_cmd_line->body_count = 0;
-       cont_cmd_line->body_list = NULL;
-       cont_cmd_line->next = NULL;
-       cont_cmd_line->line = xstrdup ("continue");
-      }
+    struct command_line *printf_cmd_line
+      = xmalloc (sizeof (struct command_line));
 
     printf_cmd_line = xmalloc (sizeof (struct command_line));
     printf_cmd_line->control_type = simple_control;
     printf_cmd_line->body_count = 0;
     printf_cmd_line->body_list = NULL;
-    printf_cmd_line->next = cont_cmd_line;
+    printf_cmd_line->next = NULL;
     printf_cmd_line->line = printf_line;
 
     breakpoint_set_commands (b, printf_cmd_line);
@@ -9628,47 +9666,47 @@ create_breakpoint (struct gdbarch *gdbarch,
      breakpoint.  */
   if (!pending)
     {
-      struct linespec_sals *lsal;
-
-      lsal = VEC_index (linespec_sals, canonical.sals, 0);
-
       if (parse_arg)
         {
-           char *rest;
-            /* Here we only parse 'arg' to separate condition
-               from thread number, so parsing in context of first
-               sal is OK.  When setting the breakpoint we'll 
-               re-parse it in context of each sal.  */
-
-            find_condition_and_thread (arg, lsal->sals.sals[0].pc, &cond_string,
-                                       &thread, &task, &rest);
-            if (cond_string)
-                make_cleanup (xfree, cond_string);
-           if (rest)
-             make_cleanup (xfree, rest);
-           if (rest)
-             extra_string = rest;
+         char *rest;
+         struct linespec_sals *lsal;
+
+         lsal = VEC_index (linespec_sals, canonical.sals, 0);
+
+         /* Here we only parse 'arg' to separate condition
+            from thread number, so parsing in context of first
+            sal is OK.  When setting the breakpoint we'll
+            re-parse it in context of each sal.  */
+
+         find_condition_and_thread (arg, lsal->sals.sals[0].pc, &cond_string,
+                                    &thread, &task, &rest);
+         if (cond_string)
+           make_cleanup (xfree, cond_string);
+         if (rest)
+           make_cleanup (xfree, rest);
+         if (rest)
+           extra_string = rest;
         }
       else
         {
-           if (*arg != '\0')
-             error (_("Garbage '%s' at end of location"), arg);
-
-            /* Create a private copy of condition string.  */
-            if (cond_string)
-            {
-                cond_string = xstrdup (cond_string);
-                make_cleanup (xfree, cond_string);
-            }
-            /* Create a private copy of any extra string.  */
-            if (extra_string)
-             {
-                extra_string = xstrdup (extra_string);
-                make_cleanup (xfree, extra_string);
-             }
+         if (*arg != '\0')
+           error (_("Garbage '%s' at end of location"), arg);
+
+         /* Create a private copy of condition string.  */
+         if (cond_string)
+           {
+             cond_string = xstrdup (cond_string);
+             make_cleanup (xfree, cond_string);
+           }
+         /* Create a private copy of any extra string.  */
+         if (extra_string)
+           {
+             extra_string = xstrdup (extra_string);
+             make_cleanup (xfree, extra_string);
+           }
         }
 
-      ops->create_breakpoints_sal (gdbarch, &canonical, lsal,
+      ops->create_breakpoints_sal (gdbarch, &canonical,
                                   cond_string, extra_string, type_wanted,
                                   tempflag ? disp_del : disp_donttouch,
                                   thread, task, ignore_count, ops,
@@ -10648,6 +10686,20 @@ print_recreate_watchpoint (struct breakpoint *b, struct ui_file *fp)
   print_recreate_thread (b, fp);
 }
 
+/* Implement the "explains_signal" breakpoint_ops method for
+   watchpoints.  */
+
+static enum bpstat_signal_value
+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 BPSTAT_SIGNAL_HIDE;
+}
+
 /* The breakpoint_ops structure to be used in hardware watchpoints.  */
 
 static struct breakpoint_ops watchpoint_breakpoint_ops;
@@ -10983,7 +11035,7 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
 
   exp_valid_block = innermost_block;
   mark = value_mark ();
-  fetch_subexp_value (exp, &pc, &val, &result, NULL);
+  fetch_subexp_value (exp, &pc, &val, &result, NULL, just_location);
 
   if (just_location)
     {
@@ -12727,7 +12779,6 @@ base_breakpoint_create_sals_from_address (char **arg,
 static void
 base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch,
                                        struct linespec_result *c,
-                                       struct linespec_sals *lsal,
                                        char *cond_string,
                                        char *extra_string,
                                        enum bptype type_wanted,
@@ -12751,11 +12802,19 @@ base_breakpoint_decode_linespec (struct breakpoint *b, char **s,
 /* The default 'explains_signal' method.  */
 
 static enum bpstat_signal_value
-base_breakpoint_explains_signal (struct breakpoint *b)
+base_breakpoint_explains_signal (struct breakpoint *b, enum gdb_signal sig)
 {
   return BPSTAT_SIGNAL_HIDE;
 }
 
+/* The default "after_condition_true" method.  */
+
+static void
+base_breakpoint_after_condition_true (struct bpstats *bs)
+{
+  /* Nothing to do.   */
+}
+
 struct breakpoint_ops base_breakpoint_ops =
 {
   base_breakpoint_dtor,
@@ -12775,7 +12834,8 @@ struct breakpoint_ops base_breakpoint_ops =
   base_breakpoint_create_sals_from_address,
   base_breakpoint_create_breakpoints_sal,
   base_breakpoint_decode_linespec,
-  base_breakpoint_explains_signal
+  base_breakpoint_explains_signal,
+  base_breakpoint_after_condition_true,
 };
 
 /* Default breakpoint_ops methods.  */
@@ -12940,7 +13000,6 @@ bkpt_create_sals_from_address (char **arg,
 static void
 bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
                             struct linespec_result *canonical,
-                            struct linespec_sals *lsal,
                             char *cond_string,
                             char *extra_string,
                             enum bptype type_wanted,
@@ -12951,7 +13010,7 @@ bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
                             int from_tty, int enabled,
                             int internal, unsigned flags)
 {
-  create_breakpoints_sal_default (gdbarch, canonical, lsal,
+  create_breakpoints_sal_default (gdbarch, canonical,
                                  cond_string, extra_string,
                                  type_wanted,
                                  disposition, thread, task,
@@ -13278,7 +13337,6 @@ tracepoint_create_sals_from_address (char **arg,
 static void
 tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
                                   struct linespec_result *canonical,
-                                  struct linespec_sals *lsal,
                                   char *cond_string,
                                   char *extra_string,
                                   enum bptype type_wanted,
@@ -13289,7 +13347,7 @@ tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
                                   int from_tty, int enabled,
                                   int internal, unsigned flags)
 {
-  create_breakpoints_sal_default (gdbarch, canonical, lsal,
+  create_breakpoints_sal_default (gdbarch, canonical,
                                  cond_string, extra_string,
                                  type_wanted,
                                  disposition, thread, task,
@@ -13369,6 +13427,44 @@ dprintf_print_recreate (struct breakpoint *tp, struct ui_file *fp)
   print_recreate_thread (tp, fp);
 }
 
+/* Implement the "after_condition_true" breakpoint_ops method for
+   dprintf.
+
+   dprintf's are implemented with regular commands in their command
+   list, but we run the commands here instead of before presenting the
+   stop to the user, as dprintf's don't actually cause a stop.  This
+   also makes it so that the commands of multiple dprintfs at the same
+   address are all handled.  */
+
+static void
+dprintf_after_condition_true (struct bpstats *bs)
+{
+  struct cleanup *old_chain;
+  struct bpstats tmp_bs = { NULL };
+  struct bpstats *tmp_bs_p = &tmp_bs;
+
+  /* dprintf's never cause a stop.  This wasn't set in the
+     check_status hook instead because that would make the dprintf's
+     condition not be evaluated.  */
+  bs->stop = 0;
+
+  /* Run the command list here.  Take ownership of it instead of
+     copying.  We never want these commands to run later in
+     bpstat_do_actions, if a breakpoint that causes a stop happens to
+     be set at same address as this dprintf, or even if running the
+     commands here throws.  */
+  tmp_bs.commands = bs->commands;
+  bs->commands = NULL;
+  old_chain = make_cleanup_decref_counted_command_line (&tmp_bs.commands);
+
+  bpstat_do_actions_1 (&tmp_bs_p);
+
+  /* 'tmp_bs.commands' will usually be NULL by now, but
+     bpstat_do_actions_1 may return early without processing the whole
+     list.  */
+  do_cleanups (old_chain);
+}
+
 /* The breakpoint_ops structure to be used on static tracepoints with
    markers (`-m').  */
 
@@ -13392,7 +13488,6 @@ strace_marker_create_sals_from_address (char **arg,
 static void
 strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
                                      struct linespec_result *canonical,
-                                     struct linespec_sals *lsal,
                                      char *cond_string,
                                      char *extra_string,
                                      enum bptype type_wanted,
@@ -13404,6 +13499,8 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
                                      int internal, unsigned flags)
 {
   int i;
+  struct linespec_sals *lsal = VEC_index (linespec_sals,
+                                         canonical->sals, 0);
 
   /* If the user is creating a static tracepoint by marker id
      (strace -m MARKER_ID), then store the sals index, so that
@@ -14125,7 +14222,6 @@ create_sals_from_address_default (char **arg,
 static void
 create_breakpoints_sal_default (struct gdbarch *gdbarch,
                                struct linespec_result *canonical,
-                               struct linespec_sals *lsal,
                                char *cond_string,
                                char *extra_string,
                                enum bptype type_wanted,
@@ -14482,25 +14578,35 @@ disable_command (char *args, int from_tty)
        if (user_breakpoint_p (bpt))
          disable_breakpoint (bpt);
     }
-  else if (strchr (args, '.'))
+  else
     {
-      struct bp_location *loc = find_location_by_number (args);
-      if (loc)
+      char *num = extract_arg (&args);
+
+      while (num)
        {
-         if (loc->enabled)
+         if (strchr (num, '.'))
            {
-             loc->enabled = 0;
-             mark_breakpoint_location_modified (loc);
+             struct bp_location *loc = find_location_by_number (num);
+
+             if (loc)
+               {
+                 if (loc->enabled)
+                   {
+                     loc->enabled = 0;
+                     mark_breakpoint_location_modified (loc);
+                   }
+                 if (target_supports_enable_disable_tracepoint ()
+                     && current_trace_status ()->running && loc->owner
+                     && is_tracepoint (loc->owner))
+                   target_disable_tracepoint (loc);
+               }
+             update_global_location_list (0);
            }
-         if (target_supports_enable_disable_tracepoint ()
-             && current_trace_status ()->running && loc->owner
-             && is_tracepoint (loc->owner))
-           target_disable_tracepoint (loc);
+         else
+           map_breakpoint_numbers (num, do_map_disable_breakpoint, NULL);
+         num = extract_arg (&args);
        }
-      update_global_location_list (0);
     }
-  else
-    map_breakpoint_numbers (args, do_map_disable_breakpoint, NULL);
 }
 
 static void
@@ -14606,25 +14712,35 @@ enable_command (char *args, int from_tty)
        if (user_breakpoint_p (bpt))
          enable_breakpoint (bpt);
     }
-  else if (strchr (args, '.'))
+  else
     {
-      struct bp_location *loc = find_location_by_number (args);
-      if (loc)
+      char *num = extract_arg (&args);
+
+      while (num)
        {
-         if (!loc->enabled)
+         if (strchr (num, '.'))
            {
-             loc->enabled = 1;
-             mark_breakpoint_location_modified (loc);
+             struct bp_location *loc = find_location_by_number (num);
+
+             if (loc)
+               {
+                 if (!loc->enabled)
+                   {
+                     loc->enabled = 1;
+                     mark_breakpoint_location_modified (loc);
+                   }
+                 if (target_supports_enable_disable_tracepoint ()
+                     && current_trace_status ()->running && loc->owner
+                     && is_tracepoint (loc->owner))
+                   target_enable_tracepoint (loc);
+               }
+             update_global_location_list (1);
            }
-         if (target_supports_enable_disable_tracepoint ()
-             && current_trace_status ()->running && loc->owner
-             && is_tracepoint (loc->owner))
-           target_enable_tracepoint (loc);
+         else
+           map_breakpoint_numbers (num, do_map_enable_breakpoint, NULL);
+         num = extract_arg (&args);
        }
-      update_global_location_list (1);
     }
-  else
-    map_breakpoint_numbers (args, do_map_enable_breakpoint, NULL);
 }
 
 /* This struct packages up disposition data for application to multiple
@@ -15389,7 +15505,6 @@ save_breakpoints (char *filename, int from_tty,
 {
   struct breakpoint *tp;
   int any = 0;
-  char *pathname;
   struct cleanup *cleanup;
   struct ui_file *fp;
   int extra_trace_bits = 0;
@@ -15425,9 +15540,9 @@ save_breakpoints (char *filename, int from_tty,
       return;
     }
 
-  pathname = tilde_expand (filename);
-  cleanup = make_cleanup (xfree, pathname);
-  fp = gdb_fopen (pathname, "w");
+  filename = tilde_expand (filename);
+  cleanup = make_cleanup (xfree, filename);
+  fp = gdb_fopen (filename, "w");
   if (!fp)
     error (_("Unable to open file '%s' for saving (%s)"),
           filename, safe_strerror (errno));
@@ -15497,9 +15612,9 @@ save_breakpoints (char *filename, int from_tty,
   if (extra_trace_bits && *default_collect)
     fprintf_unfiltered (fp, "set default-collect %s\n", default_collect);
 
-  do_cleanups (cleanup);
   if (from_tty)
     printf_filtered (_("Saved to file '%s'.\n"), filename);
+  do_cleanups (cleanup);
 }
 
 /* The `save breakpoints' command.  */
@@ -15761,6 +15876,7 @@ initialize_breakpoint_ops (void)
   ops->print_it = print_it_watchpoint;
   ops->print_mention = print_mention_watchpoint;
   ops->print_recreate = print_recreate_watchpoint;
+  ops->explains_signal = explains_signal_watchpoint;
 
   /* Masked watchpoints.  */
   ops = &masked_watchpoint_breakpoint_ops;
@@ -15865,6 +15981,7 @@ initialize_breakpoint_ops (void)
   ops->print_it = bkpt_print_it;
   ops->print_mention = bkpt_print_mention;
   ops->print_recreate = dprintf_print_recreate;
+  ops->after_condition_true = dprintf_after_condition_true;
 }
 
 /* Chain containing all defined "enable breakpoint" subcommands.  */
@@ -16446,8 +16563,7 @@ Set a dynamic printf at specified line or function.\n\
 dprintf location,format string,arg1,arg2,...\n\
 location may be a line number, function name, or \"*\" and an address.\n\
 If a line number is specified, break at start of code for that line.\n\
-If a function is specified, break at start of code for that function.\n\
-"));
+If a function is specified, break at start of code for that function."));
   set_cmd_completer (c, location_completer);
 
   add_setshow_enum_cmd ("dprintf-style", class_support,
@@ -16496,4 +16612,5 @@ agent-printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\
   automatic_hardware_breakpoints = 1;
 
   observer_attach_about_to_proceed (breakpoint_about_to_proceed);
+  observer_attach_thread_exit (remove_threaded_breakpoints);
 }
This page took 0.061486 seconds and 4 git commands to generate.