gdb/
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 9eecdf88341903dcd92fe068dfef719930aaca64..e38c54aad774b9d8bfe4f26042fc95032561de8e 100644 (file)
@@ -68,6 +68,9 @@
 #include "skip.h"
 #include "gdb_regex.h"
 #include "ax-gdb.h"
+#include "dummy-frame.h"
+
+#include "format.h"
 
 /* readline include files */
 #include "readline/readline.h"
@@ -287,6 +290,9 @@ static struct breakpoint_ops internal_breakpoint_ops;
 /* Momentary breakpoints class type.  */
 static struct breakpoint_ops momentary_breakpoint_ops;
 
+/* Momentary breakpoints for bp_longjmp and bp_exception class type.  */
+static struct breakpoint_ops longjmp_breakpoint_ops;
+
 /* The breakpoint_ops structure to be used in regular user created
    breakpoints.  */
 struct breakpoint_ops bkpt_breakpoint_ops;
@@ -297,6 +303,45 @@ static struct breakpoint_ops bkpt_probe_breakpoint_ops;
 /* Dynamic printf class type.  */
 static 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;
+   if GDB does the printing, there is better error handling if there
+   is a problem with any of the arguments, but using an inferior
+   function lets you have special-purpose printers and sending of
+   output to the same place as compiled-in print functions.  */
+
+static const char dprintf_style_gdb[] = "gdb";
+static const char dprintf_style_call[] = "call";
+static const char dprintf_style_agent[] = "agent";
+static const char *const dprintf_style_enums[] = {
+  dprintf_style_gdb,
+  dprintf_style_call,
+  dprintf_style_agent,
+  NULL
+};
+static const char *dprintf_style = dprintf_style_gdb;
+
+/* The function to use for dynamic printf if the preferred style is to
+   call into the inferior.  The value is simply a string that is
+   copied into the command, so it can be anything that GDB can
+   evaluate to a callable address, not necessarily a function name.  */
+
+static char *dprintf_function = "";
+
+/* The channel to use for dynamic printf if the preferred style is to
+   call into the inferior; if a nonempty string, it will be passed to
+   the call as the first argument, with the format string as the
+   second.  As with the dprintf function, this can be anything that
+   GDB knows how to evaluate, so in addition to common choices like
+   "stderr", this could be an app-specific expression like
+   "mystreams[curlogger]".  */
+
+static char *dprintf_channel = "";
+
+/* True if dprintf commands should continue to operate even if GDB
+   has disconnected.  */
+static int disconnected_dprintf = 1;
+
 /* A reference-counted struct command_line.  This lets multiple
    breakpoints share a single command list.  */
 struct counted_command_line
@@ -383,21 +428,13 @@ show_automatic_hardware_breakpoints (struct ui_file *file, int from_tty,
    will remove breakpoints upon stop.  If auto, GDB will behave as ON
    if in non-stop mode, and as OFF if all-stop mode.*/
 
-static const char always_inserted_auto[] = "auto";
-static const char always_inserted_on[] = "on";
-static const char always_inserted_off[] = "off";
-static const char *const always_inserted_enums[] = {
-  always_inserted_auto,
-  always_inserted_off,
-  always_inserted_on,
-  NULL
-};
-static const char *always_inserted_mode = always_inserted_auto;
+static enum auto_boolean always_inserted_mode = AUTO_BOOLEAN_AUTO;
+
 static void
 show_always_inserted_mode (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
 {
-  if (always_inserted_mode == always_inserted_auto)
+  if (always_inserted_mode == AUTO_BOOLEAN_AUTO)
     fprintf_filtered (file,
                      _("Always inserted breakpoint "
                        "mode is %s (currently %s).\n"),
@@ -411,8 +448,8 @@ show_always_inserted_mode (struct ui_file *file, int from_tty,
 int
 breakpoints_always_inserted_mode (void)
 {
-  return (always_inserted_mode == always_inserted_on
-         || (always_inserted_mode == always_inserted_auto && non_stop));
+  return (always_inserted_mode == AUTO_BOOLEAN_TRUE
+         || (always_inserted_mode == AUTO_BOOLEAN_AUTO && non_stop));
 }
 
 static const char condition_evaluation_both[] = "host or target";
@@ -752,7 +789,6 @@ static void
 set_condition_evaluation_mode (char *args, int from_tty,
                               struct cmd_list_element *c)
 {
-  struct breakpoint *b;
   const char *old_mode, *new_mode;
 
   if ((condition_evaluation_mode_1 == condition_evaluation_target)
@@ -923,7 +959,7 @@ set_breakpoint_condition (struct breakpoint *b, char *exp,
 
          innermost_block = NULL;
          arg = exp;
-         w->cond_exp = parse_exp_1 (&arg, 0, 0);
+         w->cond_exp = parse_exp_1 (&arg, 0, 0, 0);
          if (*arg)
            error (_("Junk at end of expression"));
          w->cond_exp_valid_block = innermost_block;
@@ -936,7 +972,8 @@ set_breakpoint_condition (struct breakpoint *b, char *exp,
            {
              arg = exp;
              loc->cond =
-               parse_exp_1 (&arg, block_for_pc (loc->address), 0);
+               parse_exp_1 (&arg, loc->address,
+                            block_for_pc (loc->address), 0);
              if (*arg)
                error (_("Junk at end of expression"));
            }
@@ -948,6 +985,62 @@ set_breakpoint_condition (struct breakpoint *b, char *exp,
   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)
+{
+  char *space;
+
+  text = skip_spaces (text);
+  space = skip_to_space (text);
+  if (*space == '\0')
+    {
+      int len;
+      struct breakpoint *b;
+      VEC (char_ptr) *result = NULL;
+
+      if (text[0] == '$')
+       {
+         /* We don't support completion of history indices.  */
+         if (isdigit (text[1]))
+           return NULL;
+         return complete_internalvar (&text[1]);
+       }
+
+      /* We're completing the breakpoint number.  */
+      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)
+             sprintf (location, "%d", b->number);
+           else
+             sprintf (location, "%d.%d", b->number, count);
+
+           if (strncmp (location, text, len) == 0)
+             VEC_safe_push (char_ptr, result, xstrdup (location));
+
+           ++count;
+         }
+      }
+
+      return result;
+    }
+
+  /* We're completing the expression part.  */
+  text = skip_spaces (space);
+  return expression_completer (cmd, text, word);
+}
+
 /* condition N EXP -- set break condition of breakpoint N to EXP.  */
 
 static void
@@ -1672,7 +1765,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
          b->exp = NULL;
        }
       s = b->exp_string_reparse ? b->exp_string_reparse : b->exp_string;
-      b->exp = parse_exp_1 (&s, b->exp_valid_block, 0);
+      b->exp = parse_exp_1 (&s, 0, b->exp_valid_block, 0);
       /* If the meaning of expression itself changed, the old value is
         no longer relevant.  We don't want to report a watchpoint hit
         to the user when the old value and the new value may actually
@@ -1693,7 +1786,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
            }
 
          s = b->base.cond_string;
-         b->cond_exp = parse_exp_1 (&s, b->cond_exp_valid_block, 0);
+         b->cond_exp = parse_exp_1 (&s, 0, b->cond_exp_valid_block, 0);
        }
     }
 
@@ -2080,6 +2173,196 @@ build_target_condition_list (struct bp_location *bl)
   return;
 }
 
+/* Parses a command described by string CMD into an agent expression
+   bytecode suitable for evaluation by the bytecode interpreter.
+   Return NULL if there was any error during parsing.  */
+
+static struct agent_expr *
+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;
+  struct format_piece *fpieces;
+  int nargs;
+  struct gdbarch *gdbarch = get_current_arch ();
+
+  if (!cmd)
+    return NULL;
+
+  cmdrest = cmd;
+
+  if (*cmdrest == ',')
+    ++cmdrest;
+  cmdrest = skip_spaces (cmdrest);
+
+  if (*cmdrest++ != '"')
+    error (_("No format string following the location"));
+
+  format_start = cmdrest;
+
+  fpieces = parse_format_string (&cmdrest);
+
+  old_cleanups = make_cleanup (free_format_pieces_cleanup, &fpieces);
+
+  format_end = cmdrest;
+
+  if (*cmdrest++ != '"')
+    error (_("Bad format string, non-terminated '\"'."));
+  
+  cmdrest = skip_spaces (cmdrest);
+
+  if (!(*cmdrest == ',' || *cmdrest == '\0'))
+    error (_("Invalid argument syntax"));
+
+  if (*cmdrest == ',')
+    cmdrest++;
+  cmdrest = skip_spaces (cmdrest);
+
+  /* For each argument, make an expression.  */
+
+  argvec = (struct expression **) alloca (strlen (cmd)
+                                        * sizeof (struct expression *));
+
+  nargs = 0;
+  while (*cmdrest != '\0')
+    {
+      char *cmd1;
+
+      cmd1 = cmdrest;
+      expr = parse_exp_1 (&cmd1, scope, block_for_pc (scope), 1);
+      argvec[nargs++] = expr;
+      cmdrest = cmd1;
+      if (*cmdrest == ',')
+       ++cmdrest;
+    }
+
+  /* We don't want to stop processing, so catch any errors
+     that may show up.  */
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
+    {
+      aexpr = gen_printf (scope, gdbarch, 0, 0,
+                         format_start, format_end - format_start,
+                         fpieces, nargs, argvec);
+    }
+
+  if (ex.reason < 0)
+    {
+      /* If we got here, it means the command could not be parsed to a valid
+        bytecode expression and thus can't be evaluated on the target's side.
+        It's no use iterating through the other commands.  */
+      return NULL;
+    }
+
+  do_cleanups (old_cleanups);
+
+  /* We have a valid agent expression, return it.  */
+  return aexpr;
+}
+
+/* Based on location BL, create a list of breakpoint commands to be
+   passed on to the target.  If we have duplicated locations with
+   different commands, we will add any such to the list.  */
+
+static void
+build_target_command_list (struct bp_location *bl)
+{
+  struct bp_location **locp = NULL, **loc2p;
+  int null_command_or_parse_error = 0;
+  int modified = bl->needs_update;
+  struct bp_location *loc;
+
+  /* For now, limit to agent-style dprintf breakpoints.  */
+  if (bl->owner->type != bp_dprintf
+      || strcmp (dprintf_style, dprintf_style_agent) != 0)
+    return;
+
+  if (!target_can_run_breakpoint_commands ())
+    return;
+
+  /* Do a first pass to check for locations with no assigned
+     conditions or conditions that fail to parse to a valid agent expression
+     bytecode.  If any of these happen, then it's no use to send conditions
+     to the target since this location will always trigger and generate a
+     response back to GDB.  */
+  ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address)
+    {
+      loc = (*loc2p);
+      if (is_breakpoint (loc->owner) && loc->pspace->num == bl->pspace->num)
+       {
+         if (modified)
+           {
+             struct agent_expr *aexpr;
+
+             /* Re-parse the commands since something changed.  In that
+                case we already freed the command bytecodes (see
+                force_breakpoint_reinsertion).  We just
+                need to parse the command to bytecodes again.  */
+             aexpr = parse_cmd_to_aexpr (bl->address,
+                                         loc->owner->extra_string);
+             loc->cmd_bytecode = aexpr;
+
+             if (!aexpr)
+               continue;
+           }
+
+         /* If we have a NULL bytecode expression, it means something
+            went wrong or we have a null command expression.  */
+         if (!loc->cmd_bytecode)
+           {
+             null_command_or_parse_error = 1;
+             break;
+           }
+       }
+    }
+
+  /* If anything failed, then we're not doing target-side commands,
+     and so clean up.  */
+  if (null_command_or_parse_error)
+    {
+      ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address)
+       {
+         loc = (*loc2p);
+         if (is_breakpoint (loc->owner)
+             && loc->pspace->num == bl->pspace->num)
+           {
+             /* Only go as far as the first NULL bytecode is
+                located.  */
+             if (!loc->cond_bytecode)
+               return;
+
+             free_agent_expr (loc->cond_bytecode);
+             loc->cond_bytecode = NULL;
+           }
+       }
+    }
+
+  /* No NULL commands or failed bytecode generation.  Build a command list
+     for this location's address.  */
+  ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address)
+    {
+      loc = (*loc2p);
+      if (loc->owner->extra_string
+         && is_breakpoint (loc->owner)
+         && loc->pspace->num == bl->pspace->num
+         && loc->owner->enable_state == bp_enabled
+         && loc->enabled)
+       /* Add the command to the vector.  This will be used later
+          to send the commands to the target.  */
+       VEC_safe_push (agent_expr_p, bl->target_info.tcommands,
+                      loc->cmd_bytecode);
+    }
+
+  bl->target_info.persist = 0;
+  /* Maybe flag this location as persistent.  */
+  if (bl->owner->type == bp_dprintf && disconnected_dprintf)
+    bl->target_info.persist = 1;
+}
+
 /* Insert a low-level "breakpoint" of some type.  BL is the breakpoint
    location.  Any error messages are printed to TMP_ERROR_STREAM; and
    DISABLED_BREAKS, and HW_BREAKPOINT_ERROR are used to report problems.
@@ -2120,7 +2403,8 @@ insert_bp_location (struct bp_location *bl,
   if (is_breakpoint (bl->owner))
     {
       build_target_condition_list (bl);
-      /* Reset the condition modification marker.  */
+      build_target_command_list (bl);
+      /* Reset the modification marker.  */
       bl->needs_update = 0;
     }
 
@@ -2639,6 +2923,9 @@ remove_breakpoints_pid (int pid)
     if (bl->pspace != inf->pspace)
       continue;
 
+    if (bl->owner->type == bp_dprintf)
+      continue;
+
     if (bl->inserted)
       {
        val = remove_breakpoint (bl, mark_uninserted);
@@ -3149,6 +3436,7 @@ update_breakpoints_after_exec (void)
     /* Longjmp and longjmp-resume breakpoints are also meaningless
        after an exec.  */
     if (b->type == bp_longjmp || b->type == bp_longjmp_resume
+       || b->type == bp_longjmp_call_dummy
        || b->type == bp_exception || b->type == bp_exception_resume)
       {
        delete_breakpoint (b);
@@ -3440,6 +3728,7 @@ breakpoint_init_inferior (enum inf_context context)
     switch (b->type)
       {
       case bp_call_dummy:
+      case bp_longjmp_call_dummy:
 
        /* If the call dummy breakpoint is at the entry point it will
           cause problems when the inferior is rerun, so we better get
@@ -5099,9 +5388,10 @@ bpstat_what (bpstat bs_head)
            }
          break;
        case bp_longjmp:
+       case bp_longjmp_call_dummy:
        case bp_exception:
          this_action = BPSTAT_WHAT_SET_LONGJMP_RESUME;
-         retval.is_longjmp = bptype == bp_longjmp;
+         retval.is_longjmp = bptype != bp_exception;
          break;
        case bp_longjmp_resume:
        case bp_exception_resume:
@@ -5434,6 +5724,7 @@ bptype_string (enum bptype type)
     {bp_access_watchpoint, "acc watchpoint"},
     {bp_longjmp, "longjmp"},
     {bp_longjmp_resume, "longjmp resume"},
+    {bp_longjmp_call_dummy, "longjmp for call dummy"},
     {bp_exception, "exception"},
     {bp_exception_resume, "exception resume"},
     {bp_step_resume, "step resume"},
@@ -5576,6 +5867,7 @@ print_one_breakpoint_location (struct breakpoint *b,
       case bp_finish:
       case bp_longjmp:
       case bp_longjmp_resume:
+      case bp_longjmp_call_dummy:
       case bp_exception:
       case bp_exception_resume:
       case bp_step_resume:
@@ -5770,6 +6062,15 @@ print_one_breakpoint_location (struct breakpoint *b,
        }
     }
   
+  if (!part_of_multiple && b->extra_string
+      && b->type == bp_dprintf && !b->commands)
+    {
+      annotate_field (7);
+      ui_out_text (uiout, "\t(agent printf) ");
+      ui_out_field_string (uiout, "printf", b->extra_string);
+      ui_out_text (uiout, "\n");
+    }
+
   l = b->commands ? b->commands->commands : NULL;
   if (!part_of_multiple && l)
     {
@@ -6439,6 +6740,7 @@ init_bp_location (struct bp_location *loc, const struct bp_location_ops *ops,
     case bp_finish:
     case bp_longjmp:
     case bp_longjmp_resume:
+    case bp_longjmp_call_dummy:
     case bp_exception:
     case bp_exception_resume:
     case bp_step_resume:
@@ -6598,9 +6900,10 @@ set_breakpoint_location_function (struct bp_location *loc, int explicit_loc)
     {
       int is_gnu_ifunc;
       const char *function_name;
+      CORE_ADDR func_addr;
 
       find_pc_partial_function_gnu_ifunc (loc->address, &function_name,
-                                         NULL, NULL, &is_gnu_ifunc);
+                                         &func_addr, NULL, &is_gnu_ifunc);
 
       if (is_gnu_ifunc && !explicit_loc)
        {
@@ -6621,6 +6924,9 @@ set_breakpoint_location_function (struct bp_location *loc, int explicit_loc)
              /* Create only the whole new breakpoint of this type but do not
                 mess more complicated breakpoints with multiple locations.  */
              b->type = bp_gnu_ifunc_resolver;
+             /* Remember the resolver's address for use by the return
+                breakpoint.  */
+             loc->related_address = func_addr;
            }
        }
 
@@ -6738,8 +7044,10 @@ set_longjmp_breakpoint (struct thread_info *tp, struct frame_id frame)
        enum bptype type = b->type == bp_longjmp_master ? bp_longjmp : bp_exception;
        struct breakpoint *clone;
 
+       /* longjmp_breakpoint_ops ensures INITIATING_FRAME is cleared again
+          after their removal.  */
        clone = momentary_breakpoint_from_master (b, type,
-                                                 &momentary_breakpoint_ops);
+                                                 &longjmp_breakpoint_ops);
        clone->thread = thread;
       }
 
@@ -6773,6 +7081,75 @@ delete_longjmp_breakpoint_at_next_stop (int thread)
       }
 }
 
+/* Place breakpoints of type bp_longjmp_call_dummy to catch longjmp for
+   INFERIOR_PTID thread.  Chain them all by RELATED_BREAKPOINT and return
+   pointer to any of them.  Return NULL if this system cannot place longjmp
+   breakpoints.  */
+
+struct breakpoint *
+set_longjmp_breakpoint_for_call_dummy (void)
+{
+  struct breakpoint *b, *retval = NULL;
+
+  ALL_BREAKPOINTS (b)
+    if (b->pspace == current_program_space && b->type == bp_longjmp_master)
+      {
+       struct breakpoint *new_b;
+
+       new_b = momentary_breakpoint_from_master (b, bp_longjmp_call_dummy,
+                                                 &momentary_breakpoint_ops);
+       new_b->thread = pid_to_thread_id (inferior_ptid);
+
+       /* Link NEW_B into the chain of RETVAL breakpoints.  */
+
+       gdb_assert (new_b->related_breakpoint == new_b);
+       if (retval == NULL)
+         retval = new_b;
+       new_b->related_breakpoint = retval;
+       while (retval->related_breakpoint != new_b->related_breakpoint)
+         retval = retval->related_breakpoint;
+       retval->related_breakpoint = new_b;
+      }
+
+  return retval;
+}
+
+/* Verify all existing dummy frames and their associated breakpoints for
+   THREAD.  Remove those which can no longer be found in the current frame
+   stack.
+
+   You should call this function only at places where it is safe to currently
+   unwind the whole stack.  Failed stack unwind would discard live dummy
+   frames.  */
+
+void
+check_longjmp_breakpoint_for_call_dummy (int thread)
+{
+  struct breakpoint *b, *b_tmp;
+
+  ALL_BREAKPOINTS_SAFE (b, b_tmp)
+    if (b->type == bp_longjmp_call_dummy && b->thread == thread)
+      {
+       struct breakpoint *dummy_b = b->related_breakpoint;
+
+       while (dummy_b != b && dummy_b->type != bp_call_dummy)
+         dummy_b = dummy_b->related_breakpoint;
+       if (dummy_b->type != bp_call_dummy
+           || frame_find_by_id (dummy_b->frame_id) != NULL)
+         continue;
+       
+       dummy_frame_discard (dummy_b->frame_id);
+
+       while (b->related_breakpoint != b)
+         {
+           if (b_tmp == b->related_breakpoint)
+             b_tmp = b->related_breakpoint->next;
+           delete_breakpoint (b->related_breakpoint);
+         }
+       delete_breakpoint (b);
+      }
+}
+
 void
 enable_overlay_breakpoints (void)
 {
@@ -7456,7 +7833,6 @@ catch_load_or_unload (char *arg, int from_tty, int is_load,
   struct solib_catchpoint *c;
   struct gdbarch *gdbarch = get_current_arch ();
   int tempflag;
-  regex_t compiled;
   struct cleanup *cleanup;
 
   tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
@@ -7724,7 +8100,6 @@ print_it_catch_syscall (bpstat bs)
   ptid_t ptid;
   struct target_waitstatus last;
   struct syscall s;
-  char *syscall_id;
 
   get_last_target_status (&ptid, &last);
 
@@ -8394,40 +8769,6 @@ bp_loc_is_permanent (struct bp_location *loc)
   return retval;
 }
 
-/* The style in which to perform a dynamic printf.  This is a user
-   option because different output options have different tradeoffs;
-   if GDB does the printing, there is better error handling if there
-   is a problem with any of the arguments, but using an inferior
-   function lets you have special-purpose printers and sending of
-   output to the same place as compiled-in print functions.  (Future
-   styles may include the ability to do a target-side printf.)  */
-
-static const char dprintf_style_gdb[] = "gdb";
-static const char dprintf_style_call[] = "call";
-static const char *const dprintf_style_enums[] = {
-  dprintf_style_gdb,
-  dprintf_style_call,
-  NULL
-};
-static const char *dprintf_style = dprintf_style_gdb;
-
-/* The function to use for dynamic printf if the preferred style is to
-   call into the inferior.  The value is simply a string that is
-   copied into the command, so it can be anything that GDB can
-   evaluate to a callable address, not necessarily a function name.  */
-
-static char *dprintf_function = "";
-
-/* The channel to use for dynamic printf if the preferred style is to
-   call into the inferior; if a nonempty string, it will be passed to
-   the call as the first argument, with the format string as the
-   second.  As with the dprintf function, this can be anything that
-   GDB knows how to evaluate, so in addition to common choices like
-   "stderr", this could be an app-specific expression like
-   "mystreams[curlogger]".  */
-
-static char *dprintf_channel = "";
-
 /* Build a command list for the dprintf corresponding to the current
    settings of the dprintf style options.  */
 
@@ -8451,9 +8792,9 @@ update_dprintf_command_list (struct breakpoint *b)
   if (*dprintf_args != '"')
     error (_("Bad format string, missing '\"'."));
 
-  if (strcmp (dprintf_style, "gdb") == 0)
+  if (strcmp (dprintf_style, dprintf_style_gdb) == 0)
     printf_line = xstrprintf ("printf %s", dprintf_args);
-  else if (strcmp (dprintf_style, "call") == 0)
+  else if (strcmp (dprintf_style, dprintf_style_call) == 0)
     {
       if (!dprintf_function)
        error (_("No function supplied for dprintf call"));
@@ -8468,6 +8809,16 @@ update_dprintf_command_list (struct breakpoint *b)
                                  dprintf_function,
                                  dprintf_args);
     }
+  else if (strcmp (dprintf_style, dprintf_style_agent) == 0)
+    {
+      if (target_can_run_breakpoint_commands ())
+       printf_line = xstrprintf ("agent-printf %s", dprintf_args);
+      else
+       {
+         warning (_("Target cannot run dprintf commands, falling back to GDB printf"));
+         printf_line = xstrprintf ("printf %s", dprintf_args);
+       }
+    }
   else
     internal_error (__FILE__, __LINE__,
                    _("Invalid dprintf style."));
@@ -8477,12 +8828,15 @@ update_dprintf_command_list (struct breakpoint *b)
     {
       struct command_line *printf_cmd_line, *cont_cmd_line = NULL;
 
-      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");
+      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");
+       }
 
       printf_cmd_line = xmalloc (sizeof (struct command_line));
       printf_cmd_line->control_type = simple_control;
@@ -8627,9 +8981,10 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
       if (b->cond_string)
        {
          char *arg = b->cond_string;
-         loc->cond = parse_exp_1 (&arg, block_for_pc (loc->address), 0);
+         loc->cond = parse_exp_1 (&arg, loc->address,
+                                  block_for_pc (loc->address), 0);
          if (*arg)
-              error (_("Garbage %s follows condition"), arg);
+              error (_("Garbage '%s' follows condition"), arg);
        }
 
       /* Dynamic printf requires and uses additional arguments on the
@@ -8642,7 +8997,7 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
            error (_("Format string required"));
        }
       else if (b->extra_string)
-       error (_("Garbage %s at end of command"), b->extra_string);
+       error (_("Garbage '%s' at end of command"), b->extra_string);
     }
 
   b->display_canonical = display_canonical;
@@ -8760,8 +9115,6 @@ static void
 parse_breakpoint_sals (char **address,
                       struct linespec_result *canonical)
 {
-  char *addr_start = *address;
-
   /* If no arg given, or if first arg is 'if ', use the default
      breakpoint.  */
   if ((*address) == NULL
@@ -8801,19 +9154,26 @@ parse_breakpoint_sals (char **address,
     }
   else
     {
+      struct symtab_and_line cursal = get_current_source_symtab_and_line ();
+
       /* Force almost all breakpoints to be in terms of the
          current_source_symtab (which is decode_line_1's default).
          This should produce the results we want almost all of the
-         time while leaving default_breakpoint_* alone.  */
-      if (last_displayed_sal_is_valid ())
+         time while leaving default_breakpoint_* alone.
+
+        ObjC: However, don't match an Objective-C method name which
+        may have a '+' or '-' succeeded by a '['.  */
+      if (last_displayed_sal_is_valid ()
+         && (!cursal.symtab
+             || ((strchr ("+-", (*address)[0]) != NULL)
+                 && ((*address)[1] != '['))))
        decode_line_full (address, DECODE_LINE_FUNFIRSTLINE,
                          get_last_displayed_symtab (),
                          get_last_displayed_line (),
                          canonical, NULL, NULL);
       else
        decode_line_full (address, DECODE_LINE_FUNFIRSTLINE,
-                         (struct symtab *) NULL, 0,
-                         canonical, NULL, NULL);
+                         cursal.symtab, cursal.line, canonical, NULL, NULL);
     }
 }
 
@@ -8869,6 +9229,14 @@ check_fast_tracepoint_sals (struct gdbarch *gdbarch,
     }
 }
 
+/* Issue an invalid thread ID error.  */
+
+static void ATTRIBUTE_NORETURN
+invalid_thread_id_error (int id)
+{
+  error (_("Unknown thread %d."), id);
+}
+
 /* Given TOK, a string specification of condition and thread, as
    accepted by the 'break' command, extract the condition
    string and thread number and set *COND_STRING and *THREAD.
@@ -8883,6 +9251,9 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
 {
   *cond_string = NULL;
   *thread = -1;
+  *task = 0;
+  *rest = NULL;
+
   while (tok && *tok)
     {
       char *end_tok;
@@ -8907,7 +9278,7 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
          struct expression *expr;
 
          tok = cond_start = end_tok + 1;
-         expr = parse_exp_1 (&tok, block_for_pc (pc), 0);
+         expr = parse_exp_1 (&tok, pc, block_for_pc (pc), 0);
          xfree (expr);
          cond_end = tok;
          *cond_string = savestring (cond_start, cond_end - cond_start);
@@ -8922,7 +9293,7 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
          if (tok == tmptok)
            error (_("Junk after thread keyword."));
          if (!valid_thread_id (*thread))
-           error (_("Unknown thread %d."), *thread);
+           invalid_thread_id_error (*thread);
        }
       else if (toklen >= 1 && strncmp (tok, "task", toklen) == 0)
        {
@@ -8939,7 +9310,7 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
       else if (rest)
        {
          *rest = savestring (tok, strlen (tok));
-         tok += toklen;
+         return;
        }
       else
        error (_("Junk at end of arguments."));
@@ -8953,8 +9324,6 @@ decode_static_tracepoint_spec (char **arg_p)
 {
   VEC(static_tracepoint_marker_p) *markers = NULL;
   struct symtabs_and_lines sals;
-  struct symtab_and_line sal;
-  struct symbol *sym;
   struct cleanup *old_chain;
   char *p = &(*arg_p)[3];
   char *endp;
@@ -9024,7 +9393,6 @@ create_breakpoint (struct gdbarch *gdbarch,
   struct linespec_result canonical;
   struct cleanup *old_chain;
   struct cleanup *bkpt_chain = NULL;
-  int i;
   int pending = 0;
   int task = 0;
   int prev_bkpt_count = breakpoint_count;
@@ -9136,9 +9504,7 @@ create_breakpoint (struct gdbarch *gdbarch,
                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.  */
-            cond_string = NULL;
-            thread = -1;
-           rest = NULL;
+
             find_condition_and_thread (arg, lsal->sals.sals[0].pc, &cond_string,
                                        &thread, &task, &rest);
             if (cond_string)
@@ -9189,7 +9555,18 @@ create_breakpoint (struct gdbarch *gdbarch,
       init_raw_breakpoint_without_location (b, gdbarch, type_wanted, ops);
 
       b->addr_string = copy_arg;
-      b->cond_string = NULL;
+      if (parse_condition_and_thread)
+       b->cond_string = NULL;
+      else
+       {
+         /* Create a private copy of condition string.  */
+         if (cond_string)
+           {
+             cond_string = xstrdup (cond_string);
+             make_cleanup (xfree, cond_string);
+           }
+         b->cond_string = cond_string;
+       }
       b->extra_string = NULL;
       b->ignore_count = ignore_count;
       b->disposition = tempflag ? disp_del : disp_donttouch;
@@ -9434,6 +9811,12 @@ dprintf_command (char *arg, int from_tty)
                     0);
 }
 
+static void
+agent_printf_command (char *arg, int from_tty)
+{
+  error (_("May only run agent-printf on the target"));
+}
+
 /* Implement the "breakpoint_hit" breakpoint_ops method for
    ranged breakpoints.  */
 
@@ -9444,7 +9827,7 @@ breakpoint_hit_ranged_breakpoint (const struct bp_location *bl,
                                  const struct target_waitstatus *ws)
 {
   if (ws->kind != TARGET_WAITKIND_STOPPED
-      || ws->value.sig != TARGET_SIGNAL_TRAP)
+      || ws->value.sig != GDB_SIGNAL_TRAP)
     return 0;
 
   return breakpoint_address_match_range (bl->pspace->aspace, bl->address,
@@ -9788,6 +10171,8 @@ watchpoint_exp_is_const (const struct expression *exp)
        case OP_BITSTRING:
        case OP_ARRAY:
        case OP_TYPE:
+       case OP_TYPEOF:
+       case OP_DECLTYPE:
        case OP_NAME:
        case OP_OBJC_NSSTRING:
 
@@ -9797,6 +10182,10 @@ watchpoint_exp_is_const (const struct expression *exp)
        case UNOP_ADDR:
        case UNOP_HIGH:
        case UNOP_CAST:
+
+       case UNOP_CAST_TYPE:
+       case UNOP_REINTERPRET_CAST:
+       case UNOP_DYNAMIC_CAST:
          /* Unary, binary and ternary operators: We have to check
             their operands.  If they are constant, then so is the
             result of that operation.  For instance, if A and B are
@@ -10398,7 +10787,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
 
              /* Check if the thread actually exists.  */
              if (!valid_thread_id (thread))
-               error (_("Unknown thread %d."), thread);
+               invalid_thread_id_error (thread);
            }
          else if (toklen == 4 && !strncmp (tok, "mask", 4))
            {
@@ -10430,7 +10819,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
   /* Parse the rest of the arguments.  */
   innermost_block = NULL;
   exp_start = arg;
-  exp = parse_exp_1 (&arg, 0, 0);
+  exp = parse_exp_1 (&arg, 0, 0, 0);
   exp_end = arg;
   /* Remove trailing whitespace from the expression before saving it.
      This makes the eventual display of the expression string a bit
@@ -10485,7 +10874,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
 
       innermost_block = NULL;
       tok = cond_start = end_tok + 1;
-      cond = parse_exp_1 (&tok, 0, 0);
+      cond = parse_exp_1 (&tok, 0, 0, 0);
 
       /* The watchpoint expression may not be local, but the condition
         may still be.  E.g.: `watch global if local > 0'.  */
@@ -10720,23 +11109,6 @@ watch_command_wrapper (char *arg, int from_tty, int internal)
   watch_command_1 (arg, hw_write, from_tty, 0, internal);
 }
 
-/* A helper function that looks for an argument at the start of a
-   string.  The argument must also either be at the end of the string,
-   or be followed by whitespace.  Returns 1 if it finds the argument,
-   0 otherwise.  If the argument is found, it updates *STR.  */
-
-static int
-check_for_argument (char **str, char *arg, int arg_len)
-{
-  if (strncmp (*str, arg, arg_len) == 0
-      && ((*str)[arg_len] == '\0' || isspace ((*str)[arg_len])))
-    {
-      *str += arg_len;
-      return 1;
-    }
-  return 0;
-}
-
 /* A helper function that looks for the "-location" argument and then
    calls watch_command_1.  */
 
@@ -10817,10 +11189,10 @@ until_break_command (char *arg, int from_tty, int anywhere)
 {
   struct symtabs_and_lines sals;
   struct symtab_and_line sal;
-  struct frame_info *frame = get_selected_frame (NULL);
-  struct gdbarch *frame_gdbarch = get_frame_arch (frame);
-  struct frame_id stack_frame_id = get_stack_frame_id (frame);
-  struct frame_id caller_frame_id = frame_unwind_caller_id (frame);
+  struct frame_info *frame;
+  struct gdbarch *frame_gdbarch;
+  struct frame_id stack_frame_id;
+  struct frame_id caller_frame_id;
   struct breakpoint *breakpoint;
   struct breakpoint *breakpoint2 = NULL;
   struct cleanup *old_chain;
@@ -10856,8 +11228,15 @@ until_break_command (char *arg, int from_tty, int anywhere)
 
   old_chain = make_cleanup (null_cleanup, NULL);
 
-  /* Installing a breakpoint invalidates the frame chain (as it may
-     need to switch threads), so do any frame handling first.  */
+  /* Note linespec handling above invalidates the frame chain.
+     Installing a breakpoint also invalidates the frame chain (as it
+     may need to switch threads), so do any frame handling before
+     that.  */
+
+  frame = get_selected_frame (NULL);
+  frame_gdbarch = get_frame_arch (frame);
+  stack_frame_id = get_stack_frame_id (frame);
+  caller_frame_id = frame_unwind_caller_id (frame);
 
   /* Keep within the current frame, or in frames called by the current
      one.  */
@@ -10893,7 +11272,7 @@ until_break_command (char *arg, int from_tty, int anywhere)
                                           stack_frame_id, bp_until);
   make_cleanup_delete_breakpoint (breakpoint);
 
-  proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
+  proceed (-1, GDB_SIGNAL_DEFAULT, 0);
 
   /* If we are running asynchronously, and proceed call above has
      actually managed to start the target, arrange for breakpoints to
@@ -11381,8 +11760,9 @@ clear_command (char *arg, int from_tty)
 
   if (arg)
     {
-      sals = decode_line_spec (arg, (DECODE_LINE_FUNFIRSTLINE
-                                    | DECODE_LINE_LIST_MODE));
+      sals = decode_line_with_current_source (arg,
+                                             (DECODE_LINE_FUNFIRSTLINE
+                                              | DECODE_LINE_LIST_MODE));
       default_match = 0;
     }
   else
@@ -12458,7 +12838,7 @@ bkpt_breakpoint_hit (const struct bp_location *bl,
   struct breakpoint *b = bl->owner;
 
   if (ws->kind != TARGET_WAITKIND_STOPPED
-      || ws->value.sig != TARGET_SIGNAL_TRAP)
+      || ws->value.sig != GDB_SIGNAL_TRAP)
     return 0;
 
   if (!breakpoint_address_match (bl->pspace->aspace, bl->address,
@@ -12753,6 +13133,22 @@ momentary_bkpt_print_mention (struct breakpoint *b)
   /* Nothing to mention.  These breakpoints are internal.  */
 }
 
+/* Ensure INITIATING_FRAME is cleared when no such breakpoint exists.
+
+   It gets cleared already on the removal of the first one of such placed
+   breakpoints.  This is OK as they get all removed altogether.  */
+
+static void
+longjmp_bkpt_dtor (struct breakpoint *self)
+{
+  struct thread_info *tp = find_thread_id (self->thread);
+
+  if (tp)
+    tp->initiating_frame = null_frame_id;
+
+  momentary_breakpoint_ops.dtor (self);
+}
+
 /* Specific methods for probe breakpoints.  */
 
 static int
@@ -13336,7 +13732,6 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
   struct tracepoint *tp = (struct tracepoint *) b;
   struct static_tracepoint_marker marker;
   CORE_ADDR pc;
-  int i;
 
   pc = sal.pc;
   if (sal.line)
@@ -13513,7 +13908,8 @@ update_breakpoint_locations (struct breakpoint *b,
          s = b->cond_string;
          TRY_CATCH (e, RETURN_MASK_ERROR)
            {
-             new_loc->cond = parse_exp_1 (&s, block_for_pc (sals.sals[i].pc), 
+             new_loc->cond = parse_exp_1 (&s, sals.sals[i].pc,
+                                          block_for_pc (sals.sals[i].pc), 
                                           0);
            }
          if (e.reason < 0)
@@ -13637,10 +14033,8 @@ addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
        resolve_sal_pc (&sals.sals[i]);
       if (b->condition_not_parsed && s && s[0])
        {
-         char *cond_string = 0;
-         int thread = -1;
-         int task = 0;
-         char *extra_string = NULL;
+         char *cond_string, *extra_string;
+         int thread, task;
 
          find_condition_and_thread (s, sals.sals[0].pc,
                                     &cond_string, &thread, &task,
@@ -14327,27 +14721,6 @@ invalidate_bp_value_on_memory_change (CORE_ADDR addr, int len,
       }
 }
 
-/* Use the last displayed codepoint's values, or nothing
-   if they aren't valid.  */
-
-struct symtabs_and_lines
-decode_line_spec_1 (char *string, int flags)
-{
-  struct symtabs_and_lines sals;
-
-  if (string == 0)
-    error (_("Empty line specification."));
-  if (last_displayed_sal_is_valid ())
-    sals = decode_line_1 (&string, flags,
-                         get_last_displayed_symtab (),
-                         get_last_displayed_line ());
-  else
-    sals = decode_line_1 (&string, flags, (struct symtab *) NULL, 0);
-  if (*string)
-    error (_("Junk at end of line specification: %s"), string);
-  return sals;
-}
-
 /* Create and insert a raw software breakpoint at PC.  Return an
    identifier, which should be used to remove the breakpoint later.
    In general, places which call this should be using something on the
@@ -14567,12 +14940,12 @@ catching_syscall_number (int syscall_number)
 }
 
 /* Complete syscall names.  Used by "catch syscall".  */
-static char **
+static VEC (char_ptr) *
 catch_syscall_completer (struct cmd_list_element *cmd,
                          char *text, char *word)
 {
   const char **list = get_syscall_names ();
-  char **retlist
+  VEC (char_ptr) *retlist
     = (list == NULL) ? NULL : complete_on_enum (list, text, word);
 
   xfree (list);
@@ -15163,7 +15536,10 @@ all_tracepoints (void)
    COMMAND should be a string constant containing the name of the
    command.  */
 #define BREAK_ARGS_HELP(command) \
-command" [LOCATION] [thread THREADNUM] [if CONDITION]\n\
+command" [PROBE_MODIFIER] [LOCATION] [thread THREADNUM] [if CONDITION]\n\
+PROBE_MODIFIER shall be present if the command is to be placed in a\n\
+probe point.  Accepted values are `-probe' (for a generic, automatically\n\
+guessed probe type) or `-probe-stap' (for a SystemTap probe).\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\
@@ -15189,8 +15565,7 @@ void
 add_catch_command (char *name, char *docstring,
                   void (*sfunc) (char *args, int from_tty,
                                  struct cmd_list_element *command),
-                   char **(*completer) (struct cmd_list_element *cmd,
-                                         char *text, char *word),
+                  completer_ftype *completer,
                   void *user_data_catch,
                   void *user_data_tcatch)
 {
@@ -15343,6 +15718,11 @@ initialize_breakpoint_ops (void)
   ops->print_it = momentary_bkpt_print_it;
   ops->print_mention = momentary_bkpt_print_mention;
 
+  /* Momentary breakpoints for bp_longjmp and bp_exception.  */
+  ops = &longjmp_breakpoint_ops;
+  *ops = momentary_breakpoint_ops;
+  ops->dtor = longjmp_bkpt_dtor;
+
   /* Probe breakpoints.  */
   ops = &bkpt_probe_breakpoint_ops;
   *ops = bkpt_breakpoint_ops;
@@ -15479,6 +15859,10 @@ initialize_breakpoint_ops (void)
   ops->print_recreate = bkpt_print_recreate;
 }
 
+/* Chain containing all defined "enable breakpoint" subcommands.  */
+
+static struct cmd_list_element *enablebreaklist = NULL;
+
 void
 _initialize_breakpoint (void)
 {
@@ -15518,10 +15902,11 @@ Type a line containing \"end\" to indicate the end of them.\n\
 Give \"silent\" as the first line to make the breakpoint silent;\n\
 then no output is printed when it is hit, except what the commands print."));
 
-  add_com ("condition", class_breakpoint, condition_command, _("\
+  c = add_com ("condition", class_breakpoint, condition_command, _("\
 Specify breakpoint number N to break only if COND is true.\n\
 Usage is `condition N COND', where N is an integer and COND is an\n\
 expression to be evaluated whenever breakpoint N is reached."));
+  set_cmd_completer (c, condition_completer);
 
   c = add_com ("tbreak", class_breakpoint, tbreak_command, _("\
 Set a temporary breakpoint.\n\
@@ -16009,8 +16394,8 @@ a warning will be emitted for such breakpoints."),
                           &breakpoint_set_cmdlist,
                           &breakpoint_show_cmdlist);
 
-  add_setshow_enum_cmd ("always-inserted", class_support,
-                       always_inserted_enums, &always_inserted_mode, _("\
+  add_setshow_auto_boolean_cmd ("always-inserted", class_support,
+                               &always_inserted_mode, _("\
 Set mode for inserting breakpoints."), _("\
 Show mode for inserting breakpoints."), _("\
 When this mode is off, breakpoints are inserted in inferior when it is\n\
@@ -16021,10 +16406,10 @@ the behaviour depends on the non-stop setting (see help set non-stop).\n\
 In this case, if gdb is controlling the inferior in non-stop mode, gdb\n\
 behaves as if always-inserted mode is on; if gdb is controlling the\n\
 inferior in all-stop mode, gdb behaves as if always-inserted mode is off."),
-                          NULL,
-                          &show_always_inserted_mode,
-                          &breakpoint_set_cmdlist,
-                          &breakpoint_show_cmdlist);
+                               NULL,
+                               &show_always_inserted_mode,
+                               &breakpoint_set_cmdlist,
+                               &breakpoint_show_cmdlist);
 
   add_setshow_enum_cmd ("condition-evaluation", class_breakpoint,
                        condition_evaluation_enums,
@@ -16097,6 +16482,20 @@ Show the channel to use for dynamic printf"), NULL,
                          update_dprintf_commands, NULL,
                          &setlist, &showlist);
 
+  add_setshow_boolean_cmd ("disconnected-dprintf", no_class,
+                          &disconnected_dprintf, _("\
+Set whether dprintf continues after GDB disconnects."), _("\
+Show whether dprintf continues after GDB disconnects."), _("\
+Use this to let dprintf commands continue to hit and produce output\n\
+even if GDB disconnects or detaches from the target."),
+                          NULL,
+                          NULL,
+                          &setlist, &showlist);
+
+  add_com ("agent-printf", class_vars, agent_printf_command, _("\
+agent-printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\
+(target agent only) This is useful for formatted output in user-defined commands."));
+
   automatic_hardware_breakpoints = 1;
 
   observer_attach_about_to_proceed (breakpoint_about_to_proceed);
This page took 0.045818 seconds and 4 git commands to generate.