-Wpointer-sign: gdb_byte -> char.
[binutils-gdb.git] / gdb / breakpoint.c
index bd6ceb89da72d15f5ba9b1c564b511a4f50d6095..2757c6ba359e2771bb2ff7046357568cbf7ccb5a 100644 (file)
@@ -86,6 +86,7 @@
 enum exception_event_kind
 {
   EX_EVENT_THROW,
+  EX_EVENT_RETHROW,
   EX_EVENT_CATCH
 };
 
@@ -230,11 +231,6 @@ static void stopin_command (char *arg, int from_tty);
 
 static void stopat_command (char *arg, int from_tty);
 
-static char *ep_parse_optional_if_clause (char **arg);
-
-static void catch_exception_command_1 (enum exception_event_kind ex_event, 
-                                      char *arg, int tempflag, int from_tty);
-
 static void tcatch_command (char *arg, int from_tty);
 
 static void detach_single_step_breakpoints (void);
@@ -279,14 +275,9 @@ static struct bp_location **get_first_locp_gte_addr (CORE_ADDR address);
 
 static int strace_marker_p (struct breakpoint *b);
 
-static void init_catchpoint (struct breakpoint *b,
-                            struct gdbarch *gdbarch, int tempflag,
-                            char *cond_string,
-                            const struct breakpoint_ops *ops);
-
 /* The abstract base class all breakpoint_ops structures inherit
    from.  */
-static struct breakpoint_ops base_breakpoint_ops;
+struct breakpoint_ops base_breakpoint_ops;
 
 /* The breakpoint_ops structure to be inherited by all breakpoint_ops
    that are implemented on top of software or hardware breakpoints
@@ -955,7 +946,7 @@ set_breakpoint_condition (struct breakpoint *b, char *exp,
     }
   else
     {
-      char *arg = exp;
+      const char *arg = exp;
 
       /* I don't know if it matters whether this is the string the user
         typed in or the decompiled expression.  */
@@ -990,19 +981,19 @@ set_breakpoint_condition (struct breakpoint *b, char *exp,
     }
   mark_breakpoint_modified (b);
 
-  annotate_breakpoints_changed ();
   observer_notify_breakpoint_modified (b);
 }
 
 /* Completion for the "condition" command.  */
 
 static VEC (char_ptr) *
-condition_completer (struct cmd_list_element *cmd, char *text, char *word)
+condition_completer (struct cmd_list_element *cmd,
+                    const char *text, const char *word)
 {
-  char *space;
+  const char *space;
 
-  text = skip_spaces (text);
-  space = skip_to_space (text);
+  text = skip_spaces_const (text);
+  space = skip_to_space_const (text);
   if (*space == '\0')
     {
       int len;
@@ -1047,7 +1038,7 @@ condition_completer (struct cmd_list_element *cmd, char *text, char *word)
     }
 
   /* We're completing the expression part.  */
-  text = skip_spaces (space);
+  text = skip_spaces_const (space);
   return expression_completer (cmd, text, word);
 }
 
@@ -1147,12 +1138,25 @@ validate_commands_for_breakpoint (struct breakpoint *b,
 {
   if (is_tracepoint (b))
     {
-      /* We need to verify that each top-level element of commands is
-        valid for tracepoints, that there's at most one
-        while-stepping element, and that while-stepping's body has
-        valid tracing commands excluding nested while-stepping.  */
+      struct tracepoint *t = (struct tracepoint *) b;
       struct command_line *c;
       struct command_line *while_stepping = 0;
+
+      /* Reset the while-stepping step count.  The previous commands
+         might have included a while-stepping action, while the new
+         ones might not.  */
+      t->step_count = 0;
+
+      /* We need to verify that each top-level element of commands is
+        valid for tracepoints, that there's at most one
+        while-stepping element, and that the while-stepping's body
+        has valid tracing commands excluding nested while-stepping.
+        We also need to validate the tracepoint action line in the
+        context of the tracepoint --- validate_actionline actually
+        has side effects, like setting the tracepoint's
+        while-stepping STEP_COUNT, in addition to checking if the
+        collect/teval actions parse and make sense in the
+        tracepoint's context.  */
       for (c = commands; c; c = c->next)
        {
          if (c->control_type == while_stepping_control)
@@ -1170,6 +1174,8 @@ validate_commands_for_breakpoint (struct breakpoint *b,
              else
                while_stepping = c;
            }
+
+         validate_actionline (c->line, b);
        }
       if (while_stepping)
        {
@@ -1222,7 +1228,6 @@ breakpoint_set_commands (struct breakpoint *b,
 
   decref_counted_command_line (&b->commands);
   b->commands = alloc_counted_command_line (commands);
-  annotate_breakpoints_changed ();
   observer_notify_breakpoint_modified (b);
 }
 
@@ -1271,7 +1276,7 @@ check_tracepoint_command (char *line, void *closure)
 {
   struct breakpoint *b = closure;
 
-  validate_actionline (&line, b);
+  validate_actionline (line, b);
 }
 
 /* A structure used to pass information through
@@ -1339,7 +1344,6 @@ do_map_commands_command (struct breakpoint *b, void *data)
       incref_counted_command_line (info->cmd);
       decref_counted_command_line (&b->commands);
       b->commands = info->cmd;
-      annotate_breakpoints_changed ();
       observer_notify_breakpoint_modified (b);
     }
 }
@@ -1575,7 +1579,7 @@ breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
        struct gdbarch *gdbarch = bl->gdbarch;
        const unsigned char *bp;
        CORE_ADDR placed_address = bl->target_info.placed_address;
-       unsigned placed_size = bl->target_info.placed_size;
+       int placed_size = bl->target_info.placed_size;
 
        /* Update the shadow with what we want to write to memory.  */
        memcpy (bl->target_info.shadow_contents + bptoffset,
@@ -1767,7 +1771,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
 
   if (within_current_scope && reparse)
     {
-      char *s;
+      const char *s;
 
       if (b->exp)
        {
@@ -2054,7 +2058,6 @@ static struct agent_expr *
 parse_cond_to_aexpr (CORE_ADDR scope, struct expression *cond)
 {
   struct agent_expr *aexpr = NULL;
-  struct cleanup *old_chain = NULL;
   volatile struct gdb_exception ex;
 
   if (!cond)
@@ -2192,10 +2195,9 @@ parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
   struct cleanup *old_cleanups = 0;
   struct expression *expr, **argvec;
   struct agent_expr *aexpr = NULL;
-  struct cleanup *old_chain = NULL;
   volatile struct gdb_exception ex;
-  char *cmdrest;
-  char *format_start, *format_end;
+  const char *cmdrest;
+  const char *format_start, *format_end;
   struct format_piece *fpieces;
   int nargs;
   struct gdbarch *gdbarch = get_current_arch ();
@@ -2207,7 +2209,7 @@ parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
 
   if (*cmdrest == ',')
     ++cmdrest;
-  cmdrest = skip_spaces (cmdrest);
+  cmdrest = skip_spaces_const (cmdrest);
 
   if (*cmdrest++ != '"')
     error (_("No format string following the location"));
@@ -2223,14 +2225,14 @@ parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
   if (*cmdrest++ != '"')
     error (_("Bad format string, non-terminated '\"'."));
   
-  cmdrest = skip_spaces (cmdrest);
+  cmdrest = skip_spaces_const (cmdrest);
 
   if (!(*cmdrest == ',' || *cmdrest == '\0'))
     error (_("Invalid argument syntax"));
 
   if (*cmdrest == ',')
     cmdrest++;
-  cmdrest = skip_spaces (cmdrest);
+  cmdrest = skip_spaces_const (cmdrest);
 
   /* For each argument, make an expression.  */
 
@@ -2240,7 +2242,7 @@ parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
   nargs = 0;
   while (*cmdrest != '\0')
     {
-      char *cmd1;
+      const char *cmd1;
 
       cmd1 = cmdrest;
       expr = parse_exp_1 (&cmd1, scope, block_for_pc (scope), 1);
@@ -4152,6 +4154,29 @@ bpstat_find_breakpoint (bpstat bsp, struct breakpoint *breakpoint)
   return NULL;
 }
 
+/* See breakpoint.h.  */
+
+enum bpstat_signal_value
+bpstat_explains_signal (bpstat bsp)
+{
+  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 = BPSTAT_SIGNAL_HIDE;
+
+      if (bsp->breakpoint_at != NULL)
+       newval = bsp->breakpoint_at->ops->explains_signal (bsp->breakpoint_at);
+
+      if (newval > result)
+       result = newval;
+    }
+
+  return result;
+}
+
 /* Put in *NUM the breakpoint number of the first breakpoint we are
    stopped at.  *BSP upon return is a bpstat which points to the
    remaining breakpoints stopped at (but which is not guaranteed to be
@@ -5119,7 +5144,6 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
       else if (b->ignore_count > 0)
        {
          b->ignore_count--;
-         annotate_ignore_count_change ();
          bs->stop = 0;
          /* Increase the hit count even though we don't stop.  */
          ++(b->hit_count);
@@ -5680,7 +5704,7 @@ print_breakpoint_location (struct breakpoint *b,
 
   if (b->display_canonical)
     ui_out_field_string (uiout, "what", b->addr_string);
-  else if (loc && loc->source_file)
+  else if (loc && loc->symtab)
     {
       struct symbol *sym 
        = find_pc_sect_function (loc->address, loc->section);
@@ -5693,16 +5717,13 @@ print_breakpoint_location (struct breakpoint *b,
          ui_out_wrap_hint (uiout, wrap_indent_at_field (uiout, "what"));
          ui_out_text (uiout, "at ");
        }
-      ui_out_field_string (uiout, "file", loc->source_file);
+      ui_out_field_string (uiout, "file",
+                          symtab_to_filename_for_display (loc->symtab));
       ui_out_text (uiout, ":");
-      
+
       if (ui_out_is_mi_like_p (uiout))
-       {
-         struct symtab_and_line sal = find_pc_line (loc->address, 0);
-         const char *fullname = symtab_to_fullname (sal.symtab);
-         
-         ui_out_field_string (uiout, "fullname", fullname);
-       }
+       ui_out_field_string (uiout, "fullname",
+                            symtab_to_fullname (loc->symtab));
       
       ui_out_field_int (uiout, "line", loc->line_number);
     }
@@ -5787,6 +5808,51 @@ 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'. */
+
+static void
+output_thread_groups (struct ui_out *uiout,
+                     const char *field_name,
+                     VEC(int) *inf_num,
+                     int mi_only)
+{
+  struct cleanup *back_to = make_cleanup_ui_out_list_begin_end (uiout,
+                                                               field_name);
+  int is_mi = ui_out_is_mi_like_p (uiout);
+  int inf;
+  int i;
+
+  /* For backward compatibility, don't display inferiors in CLI unless
+     there are several.  Always display them for MI. */
+  if (!is_mi && mi_only)
+    return;
+
+  for (i = 0; VEC_iterate (int, inf_num, i, inf); ++i)
+    {
+      if (is_mi)
+       {
+         char mi_group[10];
+
+         xsnprintf (mi_group, sizeof (mi_group), "i%d", inf);
+         ui_out_field_string (uiout, NULL, mi_group);
+       }
+      else
+       {
+         if (i == 0)
+           ui_out_text (uiout, " inf ");
+         else
+           ui_out_text (uiout, ", ");
+       
+         ui_out_text (uiout, plongest (inf));
+       }
+    }
+
+  do_cleanups (back_to);
+}
+
 /* Print B to gdb_stdout.  */
 
 static void
@@ -5938,35 +6004,30 @@ print_one_breakpoint_location (struct breakpoint *b,
       }
 
 
-  /* For backward compatibility, don't display inferiors unless there
-     are several.  */
-  if (loc != NULL
-      && !header_of_multiple
-      && (allflag
-         || (!gdbarch_has_global_breakpoints (target_gdbarch ())
-             && (number_of_program_spaces () > 1
-                 || number_of_inferiors () > 1)
-             /* LOC is for existing B, it cannot be in
-                moribund_locations and thus having NULL OWNER.  */
-             && loc->owner->type != bp_catchpoint)))
+  if (loc != NULL && !header_of_multiple)
     {
       struct inferior *inf;
-      int first = 1;
+      VEC(int) *inf_num = NULL;
+      int mi_only = 1;
 
-      for (inf = inferior_list; inf != NULL; inf = inf->next)
+      ALL_INFERIORS (inf)
        {
          if (inf->pspace == loc->pspace)
-           {
-             if (first)
-               {
-                 first = 0;
-                 ui_out_text (uiout, " inf ");
-               }
-             else
-               ui_out_text (uiout, ", ");
-             ui_out_text (uiout, plongest (inf->num));
-           }
+           VEC_safe_push (int, inf_num, inf->num);
        }
+
+        /* For backward compatibility, don't display inferiors in CLI unless
+          there are several.  Always display for MI. */
+       if (allflag
+           || (!gdbarch_has_global_breakpoints (target_gdbarch ())
+               && (number_of_program_spaces () > 1
+                   || number_of_inferiors () > 1)
+               /* LOC is for existing B, it cannot be in
+                  moribund_locations and thus having NULL OWNER.  */
+               && loc->owner->type != bp_catchpoint))
+       mi_only = 0;
+      output_thread_groups (uiout, "thread-groups", inf_num, mi_only);
+      VEC_free (int, inf_num);
     }
 
   if (!part_of_multiple)
@@ -7015,8 +7076,6 @@ init_raw_breakpoint (struct breakpoint *b, struct gdbarch *gdbarch,
      program space.  */
   if (bptype != bp_breakpoint && bptype != bp_hardware_breakpoint)
     b->pspace = sal.pspace;
-
-  annotate_breakpoints_changed ();
 }
 
 /* set_raw_breakpoint is a low level routine for allocating and
@@ -7951,8 +8010,6 @@ catch_unload_command_1 (char *arg, int from_tty,
   catch_load_or_unload (arg, from_tty, 0, command);
 }
 
-DEF_VEC_I(int);
-
 /* An instance of this type is used to represent a syscall catchpoint.
    It includes a "struct breakpoint" as a kind of base class; users
    downcast to "struct breakpoint *" when needed.  A breakpoint is
@@ -8349,7 +8406,7 @@ syscall_catchpoint_p (struct breakpoint *b)
    not NULL, then store it in the breakpoint.  OPS, if not NULL, is
    the breakpoint_ops structure associated to the catchpoint.  */
 
-static void
+void
 init_catchpoint (struct breakpoint *b,
                 struct gdbarch *gdbarch, int tempflag,
                 char *cond_string,
@@ -8706,11 +8763,8 @@ momentary_breakpoint_from_master (struct breakpoint *orig,
   copy->loc->section = orig->loc->section;
   copy->loc->pspace = orig->loc->pspace;
   copy->loc->probe = orig->loc->probe;
-
-  if (orig->loc->source_file != NULL)
-    copy->loc->source_file = xstrdup (orig->loc->source_file);
-
   copy->loc->line_number = orig->loc->line_number;
+  copy->loc->symtab = orig->loc->symtab;
   copy->frame_id = orig->frame_id;
   copy->thread = orig->thread;
   copy->pspace = orig->pspace;
@@ -8783,9 +8837,12 @@ add_location_to_breakpoint (struct breakpoint *b,
   adjusted_address = adjust_breakpoint_address (loc_gdbarch,
                                                sal->pc, b->type);
 
+  /* Sort the locations by their ADDRESS.  */
   loc = allocate_bp_location (b);
-  for (tmp = &(b->loc); *tmp != NULL; tmp = &((*tmp)->next))
+  for (tmp = &(b->loc); *tmp != NULL && (*tmp)->address <= adjusted_address;
+       tmp = &((*tmp)->next))
     ;
+  loc->next = *tmp;
   *tmp = loc;
 
   loc->requested_address = sal->pc;
@@ -8795,10 +8852,8 @@ add_location_to_breakpoint (struct breakpoint *b,
   gdb_assert (loc->pspace != NULL);
   loc->section = sal->section;
   loc->gdbarch = loc_gdbarch;
-
-  if (sal->symtab != NULL)
-    loc->source_file = xstrdup (sal->symtab->filename);
   loc->line_number = sal->line;
+  loc->symtab = sal->symtab;
 
   set_breakpoint_location_function (loc,
                                    sal->explicit_pc || sal->explicit_line);
@@ -9058,7 +9113,8 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
 
       if (b->cond_string)
        {
-         char *arg = b->cond_string;
+         const char *arg = b->cond_string;
+
          loc->cond = parse_exp_1 (&arg, loc->address,
                                   block_for_pc (loc->address), 0);
          if (*arg)
@@ -9329,7 +9385,7 @@ invalid_thread_id_error (int id)
    If no thread is found, *THREAD is set to -1.  */
 
 static void
-find_condition_and_thread (char *tok, CORE_ADDR pc,
+find_condition_and_thread (const char *tok, CORE_ADDR pc,
                           char **cond_string, int *thread, int *task,
                           char **rest)
 {
@@ -9340,12 +9396,12 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
 
   while (tok && *tok)
     {
-      char *end_tok;
+      const char *end_tok;
       int toklen;
-      char *cond_start = NULL;
-      char *cond_end = NULL;
+      const char *cond_start = NULL;
+      const char *cond_end = NULL;
 
-      tok = skip_spaces (tok);
+      tok = skip_spaces_const (tok);
 
       if ((*tok == '"' || *tok == ',') && rest)
        {
@@ -9353,7 +9409,7 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
          return;
        }
 
-      end_tok = skip_to_space (tok);
+      end_tok = skip_to_space_const (tok);
 
       toklen = end_tok - tok;
 
@@ -9372,24 +9428,24 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
          char *tmptok;
 
          tok = end_tok + 1;
-         tmptok = tok;
-         *thread = strtol (tok, &tok, 0);
+         *thread = strtol (tok, &tmptok, 0);
          if (tok == tmptok)
            error (_("Junk after thread keyword."));
          if (!valid_thread_id (*thread))
            invalid_thread_id_error (*thread);
+         tok = tmptok;
        }
       else if (toklen >= 1 && strncmp (tok, "task", toklen) == 0)
        {
          char *tmptok;
 
          tok = end_tok + 1;
-         tmptok = tok;
-         *task = strtol (tok, &tok, 0);
+         *task = strtol (tok, &tmptok, 0);
          if (tok == tmptok)
            error (_("Junk after task keyword."));
          if (!valid_task_id (*task))
            error (_("Unknown task %d."), *task);
+         tok = tmptok;
        }
       else if (rest)
        {
@@ -9450,20 +9506,20 @@ decode_static_tracepoint_spec (char **arg_p)
 
 /* Set a breakpoint.  This function is shared between CLI and MI
    functions for setting a breakpoint.  This function has two major
-   modes of operations, selected by the PARSE_CONDITION_AND_THREAD
-   parameter.  If non-zero, the function will parse arg, extracting
-   breakpoint location, address and thread.  Otherwise, ARG is just
-   the location of breakpoint, with condition and thread specified by
-   the COND_STRING and THREAD parameters.  If INTERNAL is non-zero,
-   the breakpoint number will be allocated from the internal
-   breakpoint count.  Returns true if any breakpoint was created;
-   false otherwise.  */
+   modes of operations, selected by the PARSE_ARG parameter.  If
+   non-zero, the function will parse ARG, extracting location,
+   condition, thread and extra string.  Otherwise, ARG is just the
+   breakpoint's location, with condition, thread, and extra string
+   specified by the COND_STRING, THREAD and EXTRA_STRING parameters.
+   If INTERNAL is non-zero, the breakpoint number will be allocated
+   from the internal breakpoint count.  Returns true if any breakpoint
+   was created; false otherwise.  */
 
 int
 create_breakpoint (struct gdbarch *gdbarch,
                   char *arg, char *cond_string,
                   int thread, char *extra_string,
-                  int parse_condition_and_thread,
+                  int parse_arg,
                   int tempflag, enum bptype type_wanted,
                   int ignore_count,
                   enum auto_boolean pending_break_support,
@@ -9581,7 +9637,7 @@ create_breakpoint (struct gdbarch *gdbarch,
 
       lsal = VEC_index (linespec_sals, canonical.sals, 0);
 
-      if (parse_condition_and_thread)
+      if (parse_arg)
         {
            char *rest;
             /* Here we only parse 'arg' to separate condition
@@ -9600,6 +9656,9 @@ create_breakpoint (struct gdbarch *gdbarch,
         }
       else
         {
+           if (*arg != '\0')
+             error (_("Garbage '%s' at end of location"), arg);
+
             /* Create a private copy of condition string.  */
             if (cond_string)
             {
@@ -9639,7 +9698,7 @@ create_breakpoint (struct gdbarch *gdbarch,
       init_raw_breakpoint_without_location (b, gdbarch, type_wanted, ops);
 
       b->addr_string = copy_arg;
-      if (parse_condition_and_thread)
+      if (parse_arg)
        b->cond_string = NULL;
       else
        {
@@ -9729,7 +9788,7 @@ resolve_sal_pc (struct symtab_and_line *sal)
     {
       if (!find_line_pc (sal->symtab, sal->line, &pc))
        error (_("No line %d in file \"%s\"."),
-              sal->line, sal->symtab->filename);
+              sal->line, symtab_to_filename_for_display (sal->symtab));
       sal->pc = pc;
 
       /* If this SAL corresponds to a breakpoint inserted using a line
@@ -9751,7 +9810,7 @@ resolve_sal_pc (struct symtab_and_line *sal)
          if (sym != NULL)
            {
              fixup_symbol_section (sym, sal->symtab->objfile);
-             sal->section = SYMBOL_OBJ_SECTION (sym);
+             sal->section = SYMBOL_OBJ_SECTION (sal->symtab->objfile, sym);
            }
          else
            {
@@ -9760,14 +9819,14 @@ resolve_sal_pc (struct symtab_and_line *sal)
                 if we have line numbers but no functions (as can
                 happen in assembly source).  */
 
-             struct minimal_symbol *msym;
+             struct bound_minimal_symbol msym;
              struct cleanup *old_chain = save_current_space_and_thread ();
 
              switch_to_program_space_and_thread (sal->pspace);
 
              msym = lookup_minimal_symbol_by_pc (sal->pc);
-             if (msym)
-               sal->section = SYMBOL_OBJ_SECTION (msym);
+             if (msym.minsym)
+               sal->section = SYMBOL_OBJ_SECTION (msym.objfile, msym.minsym);
 
              do_cleanups (old_chain);
            }
@@ -10253,6 +10312,7 @@ watchpoint_exp_is_const (const struct expression *exp)
        case OP_TYPE:
        case OP_TYPEOF:
        case OP_DECLTYPE:
+       case OP_TYPEID:
        case OP_NAME:
        case OP_OBJC_NSSTRING:
 
@@ -10438,7 +10498,6 @@ print_it_watchpoint (bpstat bs)
 {
   struct cleanup *old_chain;
   struct breakpoint *b;
-  const struct bp_location *bl;
   struct ui_file *stb;
   enum print_stop_action result;
   struct watchpoint *w;
@@ -10446,7 +10505,6 @@ print_it_watchpoint (bpstat bs)
 
   gdb_assert (bs->bp_location_at != NULL);
 
-  bl = bs->bp_location_at;
   b = bs->breakpoint_at;
   w = (struct watchpoint *) b;
 
@@ -10791,7 +10849,7 @@ is_masked_watchpoint (const struct breakpoint *b)
                 hw_read:   watch read, 
                hw_access: watch access (read or write) */
 static void
-watch_command_1 (char *arg, int accessflag, int from_tty,
+watch_command_1 (const char *arg, int accessflag, int from_tty,
                 int just_location, int internal)
 {
   volatile struct gdb_exception e;
@@ -10800,12 +10858,12 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
   const struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL;
   struct value *val, *mark, *result;
   struct frame_info *frame;
-  char *exp_start = NULL;
-  char *exp_end = NULL;
-  char *tok, *end_tok;
+  const char *exp_start = NULL;
+  const char *exp_end = NULL;
+  const char *tok, *end_tok;
   int toklen = -1;
-  char *cond_start = NULL;
-  char *cond_end = NULL;
+  const char *cond_start = NULL;
+  const char *cond_end = NULL;
   enum bptype bp_type;
   int thread = -1;
   int pc = 0;
@@ -10814,15 +10872,19 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
   int use_mask = 0;
   CORE_ADDR mask = 0;
   struct watchpoint *w;
+  char *expression;
+  struct cleanup *back_to;
 
   /* Make sure that we actually have parameters to parse.  */
   if (arg != NULL && arg[0] != '\0')
     {
-      char *value_start;
+      const char *value_start;
+
+      exp_end = arg + strlen (arg);
 
       /* Look for "parameter value" pairs at the end
         of the arguments string.  */
-      for (tok = arg + strlen (arg) - 1; tok > arg; tok--)
+      for (tok = exp_end - 1; tok > arg; tok--)
        {
          /* Skip whitespace at the end of the argument list.  */
          while (tok > arg && (*tok == ' ' || *tok == '\t'))
@@ -10892,13 +10954,19 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
 
          /* Truncate the string and get rid of the "parameter value" pair before
             the arguments string is parsed by the parse_exp_1 function.  */
-         *tok = '\0';
+         exp_end = tok;
        }
     }
+  else
+    exp_end = arg;
 
-  /* Parse the rest of the arguments.  */
+  /* Parse the rest of the arguments.  From here on out, everything
+     is in terms of a newly allocated string instead of the original
+     ARG.  */
   innermost_block = NULL;
-  exp_start = arg;
+  expression = savestring (arg, exp_end - arg);
+  back_to = make_cleanup (xfree, expression);
+  exp_start = arg = expression;
   exp = parse_exp_1 (&arg, 0, 0, 0);
   exp_end = arg;
   /* Remove trailing whitespace from the expression before saving it.
@@ -10944,8 +11012,8 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
   else if (val != NULL)
     release_value (val);
 
-  tok = skip_spaces (arg);
-  end_tok = skip_to_space (tok);
+  tok = skip_spaces_const (arg);
+  end_tok = skip_to_space_const (tok);
 
   toklen = end_tok - tok;
   if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
@@ -11097,6 +11165,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
     }
 
   install_breakpoint (internal, b, 1);
+  do_cleanups (back_to);
 }
 
 /* Return count of debug registers needed to watch the given expression.
@@ -11385,7 +11454,7 @@ until_break_command (char *arg, int from_tty, int anywhere)
    it updates arg to point to the first character following the parsed
    if clause in the arg string.  */
 
-static char *
+char *
 ep_parse_optional_if_clause (char **arg)
 {
   char *cond_string;
@@ -11498,180 +11567,6 @@ catch_exec_command_1 (char *arg, int from_tty,
   install_breakpoint (0, &c->base, 1);
 }
 
-static enum print_stop_action
-print_it_exception_catchpoint (bpstat bs)
-{
-  struct ui_out *uiout = current_uiout;
-  struct breakpoint *b = bs->breakpoint_at;
-  int bp_temp, bp_throw;
-
-  annotate_catchpoint (b->number);
-
-  bp_throw = strstr (b->addr_string, "throw") != NULL;
-  if (b->loc->address != b->loc->requested_address)
-    breakpoint_adjustment_warning (b->loc->requested_address,
-                                  b->loc->address,
-                                  b->number, 1);
-  bp_temp = b->disposition == disp_del;
-  ui_out_text (uiout, 
-              bp_temp ? "Temporary catchpoint "
-                      : "Catchpoint ");
-  if (!ui_out_is_mi_like_p (uiout))
-    ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout,
-              bp_throw ? " (exception thrown), "
-                       : " (exception caught), ");
-  if (ui_out_is_mi_like_p (uiout))
-    {
-      ui_out_field_string (uiout, "reason", 
-                          async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
-      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
-      ui_out_field_int (uiout, "bkptno", b->number);
-    }
-  return PRINT_SRC_AND_LOC;
-}
-
-static void
-print_one_exception_catchpoint (struct breakpoint *b, 
-                               struct bp_location **last_loc)
-{
-  struct value_print_options opts;
-  struct ui_out *uiout = current_uiout;
-
-  get_user_print_options (&opts);
-  if (opts.addressprint)
-    {
-      annotate_field (4);
-      if (b->loc == NULL || b->loc->shlib_disabled)
-       ui_out_field_string (uiout, "addr", "<PENDING>");
-      else
-       ui_out_field_core_addr (uiout, "addr",
-                               b->loc->gdbarch, b->loc->address);
-    }
-  annotate_field (5);
-  if (b->loc)
-    *last_loc = b->loc;
-  if (strstr (b->addr_string, "throw") != NULL)
-    {
-      ui_out_field_string (uiout, "what", "exception throw");
-      if (ui_out_is_mi_like_p (uiout))
-       ui_out_field_string (uiout, "catch-type", "throw");
-    }
-  else
-    {
-      ui_out_field_string (uiout, "what", "exception catch");
-      if (ui_out_is_mi_like_p (uiout))
-       ui_out_field_string (uiout, "catch-type", "catch");
-    }
-}
-
-static void
-print_mention_exception_catchpoint (struct breakpoint *b)
-{
-  struct ui_out *uiout = current_uiout;
-  int bp_temp;
-  int bp_throw;
-
-  bp_temp = b->disposition == disp_del;
-  bp_throw = strstr (b->addr_string, "throw") != NULL;
-  ui_out_text (uiout, bp_temp ? _("Temporary catchpoint ")
-                             : _("Catchpoint "));
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, bp_throw ? _(" (throw)")
-                              : _(" (catch)"));
-}
-
-/* Implement the "print_recreate" breakpoint_ops method for throw and
-   catch catchpoints.  */
-
-static void
-print_recreate_exception_catchpoint (struct breakpoint *b, 
-                                    struct ui_file *fp)
-{
-  int bp_temp;
-  int bp_throw;
-
-  bp_temp = b->disposition == disp_del;
-  bp_throw = strstr (b->addr_string, "throw") != NULL;
-  fprintf_unfiltered (fp, bp_temp ? "tcatch " : "catch ");
-  fprintf_unfiltered (fp, bp_throw ? "throw" : "catch");
-  print_recreate_thread (b, fp);
-}
-
-static struct breakpoint_ops gnu_v3_exception_catchpoint_ops;
-
-static int
-handle_gnu_v3_exceptions (int tempflag, char *cond_string,
-                         enum exception_event_kind ex_event, int from_tty)
-{
-  char *trigger_func_name;
-  if (ex_event == EX_EVENT_CATCH)
-    trigger_func_name = "__cxa_begin_catch";
-  else
-    trigger_func_name = "__cxa_throw";
-
-  create_breakpoint (get_current_arch (),
-                    trigger_func_name, cond_string, -1, NULL,
-                    0 /* condition and thread are valid.  */,
-                    tempflag, bp_breakpoint,
-                    0,
-                    AUTO_BOOLEAN_TRUE /* pending */,
-                    &gnu_v3_exception_catchpoint_ops, from_tty,
-                    1 /* enabled */,
-                    0 /* internal */,
-                    0);
-
-  return 1;
-}
-
-/* Deal with "catch catch" and "catch throw" commands.  */
-
-static void
-catch_exception_command_1 (enum exception_event_kind ex_event, char *arg,
-                          int tempflag, int from_tty)
-{
-  char *cond_string = NULL;
-
-  if (!arg)
-    arg = "";
-  arg = skip_spaces (arg);
-
-  cond_string = ep_parse_optional_if_clause (&arg);
-
-  if ((*arg != '\0') && !isspace (*arg))
-    error (_("Junk at end of arguments."));
-
-  if (ex_event != EX_EVENT_THROW
-      && ex_event != EX_EVENT_CATCH)
-    error (_("Unsupported or unknown exception event; cannot catch it"));
-
-  if (handle_gnu_v3_exceptions (tempflag, cond_string, ex_event, from_tty))
-    return;
-
-  warning (_("Unsupported with this platform/compiler combination."));
-}
-
-/* Implementation of "catch catch" command.  */
-
-static void
-catch_catch_command (char *arg, int from_tty, struct cmd_list_element *command)
-{
-  int tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
-
-  catch_exception_command_1 (EX_EVENT_CATCH, arg, tempflag, from_tty);
-}
-
-/* Implementation of "catch throw" command.  */
-
-static void
-catch_throw_command (char *arg, int from_tty, struct cmd_list_element *command)
-{
-  int tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
-
-  catch_exception_command_1 (EX_EVENT_THROW, arg, tempflag, from_tty);
-}
-
 void
 init_ada_exception_breakpoint (struct breakpoint *b,
                               struct gdbarch *gdbarch,
@@ -11723,8 +11618,7 @@ catch_syscall_split_args (char *arg)
       struct syscall s;
 
       /* Skip whitespace.  */
-      while (isspace (*arg))
-       arg++;
+      arg = skip_spaces (arg);
 
       for (i = 0; i < 127 && arg[i] && !isspace (arg[i]); ++i)
        cur_name[i] = arg[i];
@@ -11900,7 +11794,7 @@ clear_command (char *arg, int from_tty)
   make_cleanup (VEC_cleanup (breakpoint_p), &found);
   for (i = 0; i < sals.nelts; i++)
     {
-      int is_abs;
+      const char *sal_fullname;
 
       /* If exact pc given, clear bpts at that pc.
          If line given (pc == 0), clear all bpts on specified line.
@@ -11915,7 +11809,8 @@ clear_command (char *arg, int from_tty)
          1              0             <can't happen> */
 
       sal = sals.sals[i];
-      is_abs = sal.symtab == NULL ? 1 : IS_ABSOLUTE_PATH (sal.symtab->filename);
+      sal_fullname = (sal.symtab == NULL
+                     ? NULL : symtab_to_fullname (sal.symtab));
 
       /* Find all matching breakpoints and add them to 'found'.  */
       ALL_BREAKPOINTS (b)
@@ -11938,19 +11833,13 @@ clear_command (char *arg, int from_tty)
                  int line_match = 0;
 
                  if ((default_match || sal.explicit_line)
-                     && loc->source_file != NULL
-                     && sal.symtab != NULL
+                     && loc->symtab != NULL
+                     && sal_fullname != NULL
                      && sal.pspace == loc->pspace
-                     && loc->line_number == sal.line)
-                   {
-                     if (filename_cmp (loc->source_file,
-                                       sal.symtab->filename) == 0)
-                       line_match = 1;
-                     else if (!IS_ABSOLUTE_PATH (sal.symtab->filename)
-                              && compare_filenames_for_search (loc->source_file,
-                                                               sal.symtab->filename))
-                       line_match = 1;
-                   }
+                     && loc->line_number == sal.line
+                     && filename_cmp (symtab_to_fullname (loc->symtab),
+                                      sal_fullname) == 0)
+                   line_match = 1;
 
                  if (pc_match || line_match)
                    {
@@ -11998,7 +11887,6 @@ clear_command (char *arg, int from_tty)
       else
        printf_unfiltered (_("Deleted breakpoints "));
     }
-  annotate_breakpoints_changed ();
 
   for (ix = 0; VEC_iterate(breakpoint_p, found, ix, b); ix++)
     {
@@ -12668,7 +12556,6 @@ bpstat_remove_breakpoint_callback (struct thread_info *th, void *data)
 static void
 say_where (struct breakpoint *b)
 {
-  struct ui_out *uiout = current_uiout;
   struct value_print_options opts;
 
   get_user_print_options (&opts);
@@ -12681,19 +12568,20 @@ say_where (struct breakpoint *b)
     }
   else
     {
-      if (opts.addressprint || b->loc->source_file == NULL)
+      if (opts.addressprint || b->loc->symtab == NULL)
        {
          printf_filtered (" at ");
          fputs_filtered (paddress (b->loc->gdbarch, b->loc->address),
                          gdb_stdout);
        }
-      if (b->loc->source_file)
+      if (b->loc->symtab != NULL)
        {
          /* If there is a single location, we can print the location
             more nicely.  */
          if (b->loc->next == NULL)
            printf_filtered (": file %s, line %d.",
-                            b->loc->source_file, b->loc->line_number);
+                            symtab_to_filename_for_display (b->loc->symtab),
+                            b->loc->line_number);
          else
            /* This is not ideal, but each location may have a
               different file name, and this at least reflects the
@@ -12721,7 +12609,6 @@ bp_location_dtor (struct bp_location *self)
   if (self->cond_bytecode)
     free_agent_expr (self->cond_bytecode);
   xfree (self->function_name);
-  xfree (self->source_file);
 }
 
 static const struct bp_location_ops bp_location_ops =
@@ -12737,6 +12624,7 @@ base_breakpoint_dtor (struct breakpoint *self)
 {
   decref_counted_command_line (&self->commands);
   xfree (self->cond_string);
+  xfree (self->extra_string);
   xfree (self->addr_string);
   xfree (self->filter);
   xfree (self->addr_string_range_end);
@@ -12865,7 +12753,15 @@ base_breakpoint_decode_linespec (struct breakpoint *b, char **s,
   internal_error_pure_virtual_called ();
 }
 
-static struct breakpoint_ops base_breakpoint_ops =
+/* The default 'explains_signal' method.  */
+
+static enum bpstat_signal_value
+base_breakpoint_explains_signal (struct breakpoint *b)
+{
+  return BPSTAT_SIGNAL_HIDE;
+}
+
+struct breakpoint_ops base_breakpoint_ops =
 {
   base_breakpoint_dtor,
   base_breakpoint_allocate_location,
@@ -12884,6 +12780,7 @@ static 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
 };
 
 /* Default breakpoint_ops methods.  */
@@ -12927,8 +12824,6 @@ bkpt_breakpoint_hit (const struct bp_location *bl,
                     struct address_space *aspace, CORE_ADDR bp_addr,
                     const struct target_waitstatus *ws)
 {
-  struct breakpoint *b = bl->owner;
-
   if (ws->kind != TARGET_WAITKIND_STOPPED
       || ws->value.sig != GDB_SIGNAL_TRAP)
     return 0;
@@ -13122,7 +13017,6 @@ internal_bkpt_check_status (bpstat bs)
 static enum print_stop_action
 internal_bkpt_print_it (bpstat bs)
 {
-  struct ui_out *uiout = current_uiout;
   struct breakpoint *b;
 
   b = bs->breakpoint_at;
@@ -13441,6 +13335,35 @@ tracepoint_probe_decode_linespec (struct breakpoint *b, char **s,
 
 static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
 
+/* Dprintf breakpoint_ops methods.  */
+
+static void
+dprintf_re_set (struct breakpoint *b)
+{
+  breakpoint_re_set_default (b);
+
+  /* This breakpoint could have been pending, and be resolved now, and
+     if so, we should now have the extra string.  If we don't, the
+     dprintf was malformed when created, but we couldn't tell because
+     we can't extract the extra string until the location is
+     resolved.  */
+  if (b->loc != NULL && b->extra_string == NULL)
+    error (_("Format string required"));
+
+  /* 1 - connect to target 1, that can run breakpoint commands.
+     2 - create a dprintf, which resolves fine.
+     3 - disconnect from target 1
+     4 - connect to target 2, that can NOT run breakpoint commands.
+
+     After steps #3/#4, you'll want the dprintf command list to
+     be updated, because target 1 and 2 may well return different
+     answers for target_can_run_breakpoint_commands().
+     Given absence of finer grained resetting, we get to do
+     it all the time.  */
+  if (b->extra_string != NULL)
+    update_dprintf_command_list (b);
+}
+
 /* The breakpoint_ops structure to be used on static tracepoints with
    markers (`-m').  */
 
@@ -13884,7 +13807,8 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
                                   SYMBOL_PRINT_NAME (sym));
              ui_out_text (uiout, " at ");
            }
-         ui_out_field_string (uiout, "file", sal2.symtab->filename);
+         ui_out_field_string (uiout, "file",
+                              symtab_to_filename_for_display (sal2.symtab));
          ui_out_text (uiout, ":");
 
          if (ui_out_is_mi_like_p (uiout))
@@ -13898,16 +13822,11 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
          ui_out_text (uiout, "\n");
 
          b->loc->line_number = sal2.line;
-
-         xfree (b->loc->source_file);
-         if (sym)
-           b->loc->source_file = xstrdup (sal2.symtab->filename);
-         else
-           b->loc->source_file = NULL;
+         b->loc->symtab = sym != NULL ? sal2.symtab : NULL;
 
          xfree (b->addr_string);
          b->addr_string = xstrprintf ("%s:%d",
-                                      sal2.symtab->filename,
+                                  symtab_to_filename_for_display (sal2.symtab),
                                       b->loc->line_number);
 
          /* Might be nice to check if function changed, and warn if
@@ -13993,7 +13912,7 @@ update_breakpoint_locations (struct breakpoint *b,
         old symtab.  */
       if (b->cond_string != NULL)
        {
-         char *s;
+         const char *s;
          volatile struct gdb_exception e;
 
          s = b->cond_string;
@@ -14377,7 +14296,6 @@ set_ignore_count (int bptnum, int count, int from_tty)
                               "crossings of breakpoint %d."),
                             count, bptnum);
        }
-      annotate_breakpoints_changed ();
       observer_notify_breakpoint_modified (b);
       return;
     }
@@ -14642,8 +14560,7 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
   bpt->disposition = disposition;
   bpt->enable_count = count;
   update_global_location_list (1);
-  annotate_breakpoints_changed ();
-  
+
   observer_notify_breakpoint_modified (bpt);
 }
 
@@ -15031,7 +14948,7 @@ catching_syscall_number (int syscall_number)
 /* Complete syscall names.  Used by "catch syscall".  */
 static VEC (char_ptr) *
 catch_syscall_completer (struct cmd_list_element *cmd,
-                         char *text, char *word)
+                         const char *text, const char *word)
 {
   const char **list = get_syscall_names ();
   VEC (char_ptr) *retlist
@@ -15328,9 +15245,7 @@ trace_pass_command (char *args, int from_tty)
 
   count = strtoul (args, &args, 10);   /* Count comes first, then TP num.  */
 
-  while (*args && isspace ((int) *args))
-    args++;
-
+  args = skip_spaces (args);
   if (*args && strncasecmp (args, "all", 3) == 0)
     {
       struct breakpoint *b;
@@ -15742,6 +15657,18 @@ pc_at_non_inline_function (struct address_space *aspace, CORE_ADDR pc,
   return 0;
 }
 
+/* Remove any references to OBJFILE which is going to be freed.  */
+
+void
+breakpoint_free_objfile (struct objfile *objfile)
+{
+  struct bp_location **locp, *loc;
+
+  ALL_BP_LOCATIONS (loc, locp)
+    if (loc->symtab != NULL && loc->symtab->objfile == objfile)
+      loc->symtab = NULL;
+}
+
 void
 initialize_breakpoint_ops (void)
 {
@@ -15815,14 +15742,6 @@ initialize_breakpoint_ops (void)
   ops->create_sals_from_address = bkpt_probe_create_sals_from_address;
   ops->decode_linespec = bkpt_probe_decode_linespec;
 
-  /* GNU v3 exception catchpoints.  */
-  ops = &gnu_v3_exception_catchpoint_ops;
-  *ops = bkpt_breakpoint_ops;
-  ops->print_it = print_it_exception_catchpoint;
-  ops->print_one = print_one_exception_catchpoint;
-  ops->print_mention = print_mention_exception_catchpoint;
-  ops->print_recreate = print_recreate_exception_catchpoint;
-
   /* Watchpoints.  */
   ops = &watchpoint_breakpoint_ops;
   *ops = base_breakpoint_ops;
@@ -15936,7 +15855,7 @@ initialize_breakpoint_ops (void)
 
   ops = &dprintf_breakpoint_ops;
   *ops = bkpt_base_breakpoint_ops;
-  ops->re_set = bkpt_re_set;
+  ops->re_set = dprintf_re_set;
   ops->resources_needed = bkpt_resources_needed;
   ops->print_it = bkpt_print_it;
   ops->print_mention = bkpt_print_mention;
@@ -16238,19 +16157,6 @@ Set temporary catchpoints to catch events."),
                  &tcatch_cmdlist, "tcatch ",
                  0/*allow-unknown*/, &cmdlist);
 
-  /* Add catch and tcatch sub-commands.  */
-  add_catch_command ("catch", _("\
-Catch an exception, when caught."),
-                    catch_catch_command,
-                     NULL,
-                    CATCH_PERMANENT,
-                    CATCH_TEMPORARY);
-  add_catch_command ("throw", _("\
-Catch an exception, when thrown."),
-                    catch_throw_command,
-                     NULL,
-                    CATCH_PERMANENT,
-                    CATCH_TEMPORARY);
   add_catch_command ("fork", _("Catch calls to fork."),
                     catch_fork_command_1,
                      NULL,