gdb/
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index ce35da29edc8312aad4a62e00df714475e2e42b1..a867b10d55c13307da5c2a8888889d02dcb52ff6 100644 (file)
 #include "jit.h"
 #include "xml-syscall.h"
 #include "parser-defs.h"
+#include "gdb_regex.h"
+#include "probe.h"
 #include "cli/cli-utils.h"
 #include "continuations.h"
 #include "stack.h"
 #include "skip.h"
-#include "record.h"
 #include "gdb_regex.h"
 #include "ax-gdb.h"
 
@@ -108,11 +109,11 @@ static void create_sals_from_address_default (char **,
 static void create_breakpoints_sal_default (struct gdbarch *,
                                            struct linespec_result *,
                                            struct linespec_sals *,
-                                           char *, enum bptype,
+                                           char *, char *, enum bptype,
                                            enum bpdisp, int, int,
                                            int,
                                            const struct breakpoint_ops *,
-                                           int, int, int);
+                                           int, int, int, unsigned);
 
 static void decode_linespec_default (struct breakpoint *, char **,
                                     struct symtabs_and_lines *);
@@ -290,6 +291,12 @@ static struct breakpoint_ops momentary_breakpoint_ops;
    breakpoints.  */
 struct breakpoint_ops bkpt_breakpoint_ops;
 
+/* Breakpoints set on probes.  */
+static struct breakpoint_ops bkpt_probe_breakpoint_ops;
+
+/* Dynamic printf class type.  */
+static struct breakpoint_ops dprintf_breakpoint_ops;
+
 /* A reference-counted struct command_line.  This lets multiple
    breakpoints share a single command list.  */
 struct counted_command_line
@@ -404,9 +411,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))
-         && !RECORD_IS_USED);
+  return (always_inserted_mode == always_inserted_on
+         || (always_inserted_mode == always_inserted_auto && non_stop));
 }
 
 static const char condition_evaluation_both[] = "host or target";
@@ -746,7 +752,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)
@@ -761,6 +766,10 @@ set_condition_evaluation_mode (char *args, int from_tty,
   new_mode = translate_condition_evaluation_mode (condition_evaluation_mode_1);
   old_mode = translate_condition_evaluation_mode (condition_evaluation_mode);
 
+  /* Flip the switch.  Flip it even if OLD_MODE == NEW_MODE as one of the
+     settings was "auto".  */
+  condition_evaluation_mode = condition_evaluation_mode_1;
+
   /* Only update the mode if the user picked a different one.  */
   if (new_mode != old_mode)
     {
@@ -772,9 +781,6 @@ set_condition_evaluation_mode (char *args, int from_tty,
         "target" -> "host": Remove all the conditions from the target.
       */
 
-      /* Flip the switch.  */
-      condition_evaluation_mode = condition_evaluation_mode_1;
-
       if (new_mode == condition_evaluation_target)
        {
          /* Mark everything modified and synch conditions with the
@@ -1317,6 +1323,10 @@ bp_location_has_shadow (struct bp_location *bl)
 /* Update BUF, which is LEN bytes read from the target address MEMADDR,
    by replacing any memory breakpoints with their shadowed contents.
 
+   If READBUF is not NULL, this buffer must not overlap with any of
+   the breakpoint location's shadow_contents buffers.  Otherwise,
+   a failed assertion internal error will be raised.
+
    The range of shadowed area by each bp_location is:
      bl->address - bp_location_placed_address_before_address_max
      up to bl->address + bp_location_shadow_len_after_address_max
@@ -1445,6 +1455,12 @@ breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
 
     if (readbuf != NULL)
       {
+       /* Verify that the readbuf buffer does not overlap with
+          the shadow_contents buffer.  */
+       gdb_assert (bl->target_info.shadow_contents >= readbuf + len
+                   || readbuf >= (bl->target_info.shadow_contents
+                                  + bl->target_info.shadow_len));
+
        /* Update the read buffer with this inserted breakpoint's
           shadow.  */
        memcpy (readbuf + bp_addr - memaddr,
@@ -1480,7 +1496,8 @@ int
 is_breakpoint (const struct breakpoint *bpt)
 {
   return (bpt->type == bp_breakpoint
-         || bpt->type == bp_hardware_breakpoint);
+         || bpt->type == bp_hardware_breakpoint
+         || bpt->type == bp_dprintf);
 }
 
 /* Return true if BPT is of any hardware watchpoint kind.  */
@@ -2081,8 +2098,15 @@ insert_bp_location (struct bp_location *bl,
   if (!should_be_inserted (bl) || (bl->inserted && !bl->needs_update))
     return 0;
 
-  /* Initialize the target-specific information.  */
-  memset (&bl->target_info, 0, sizeof (bl->target_info));
+  /* Note we don't initialize bl->target_info, as that wipes out
+     the breakpoint location's shadow_contents if the breakpoint
+     is still inserted at that location.  This in turn breaks
+     target_read_memory which depends on these buffers when
+     a memory read is requested at the breakpoint location:
+     Once the target_info has been wiped, we fail to see that
+     we have a breakpoint inserted at that address and thus
+     read the breakpoint instead of returning the data saved in
+     the breakpoint location's shadow contents.  */
   bl->target_info.placed_address = bl->address;
   bl->target_info.placed_address_space = bl->pspace->aspace;
   bl->target_info.length = bl->length;
@@ -2407,6 +2431,19 @@ insert_breakpoints (void)
     insert_breakpoint_locations ();
 }
 
+/* Invoke CALLBACK for each of bp_location.  */
+
+void
+iterate_over_bp_locations (walk_bp_location_callback callback)
+{
+  struct bp_location *loc, **loc_tmp;
+
+  ALL_BP_LOCATIONS (loc, loc_tmp)
+    {
+      callback (loc, NULL);
+    }
+}
+
 /* This is used when we need to synch breakpoint conditions between GDB and the
    target.  It is the case with deleting and disabling of breakpoints when using
    always-inserted mode.  */
@@ -2710,11 +2747,23 @@ struct breakpoint_objfile_data
   /* Minimal symbol(s) for "longjmp", "siglongjmp", etc. (if any).  */
   struct minimal_symbol *longjmp_msym[NUM_LONGJMP_NAMES];
 
+  /* True if we have looked for longjmp probes.  */
+  int longjmp_searched;
+
+  /* SystemTap probe points for longjmp (if any).  */
+  VEC (probe_p) *longjmp_probes;
+
   /* Minimal symbol for "std::terminate()" (if any).  */
   struct minimal_symbol *terminate_msym;
 
   /* Minimal symbol for "_Unwind_DebugHook" (if any).  */
   struct minimal_symbol *exception_msym;
+
+  /* True if we have looked for exception probes.  */
+  int exception_searched;
+
+  /* SystemTap probe points for unwinding (if any).  */
+  VEC (probe_p) *exception_probes;
 };
 
 static const struct objfile_data *breakpoint_objfile_key;
@@ -2750,6 +2799,15 @@ get_breakpoint_objfile_data (struct objfile *objfile)
   return bp_objfile_data;
 }
 
+static void
+free_breakpoint_probes (struct objfile *obj, void *data)
+{
+  struct breakpoint_objfile_data *bp_objfile_data = data;
+
+  VEC_free (probe_p, bp_objfile_data->longjmp_probes);
+  VEC_free (probe_p, bp_objfile_data->exception_probes);
+}
+
 static void
 create_overlay_event_breakpoint (void)
 {
@@ -2827,6 +2885,37 @@ create_longjmp_master_breakpoint (void)
 
       bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
+      if (!bp_objfile_data->longjmp_searched)
+       {
+         bp_objfile_data->longjmp_probes
+           = find_probes_in_objfile (objfile, "libc", "longjmp");
+         bp_objfile_data->longjmp_searched = 1;
+       }
+
+      if (bp_objfile_data->longjmp_probes != NULL)
+       {
+         int i;
+         struct probe *probe;
+         struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
+         for (i = 0;
+              VEC_iterate (probe_p,
+                           bp_objfile_data->longjmp_probes,
+                           i, probe);
+              ++i)
+           {
+             struct breakpoint *b;
+
+             b = create_internal_breakpoint (gdbarch, probe->address,
+                                             bp_longjmp_master,
+                                             &internal_breakpoint_ops);
+             b->addr_string = xstrdup ("-probe-stap libc:longjmp");
+             b->enable_state = bp_disabled;
+           }
+
+         continue;
+       }
+
       for (i = 0; i < NUM_LONGJMP_NAMES; i++)
        {
          struct breakpoint *b;
@@ -2937,6 +3026,40 @@ create_exception_master_breakpoint (void)
 
       bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
+      /* 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");
+         bp_objfile_data->exception_searched = 1;
+       }
+
+      if (bp_objfile_data->exception_probes != NULL)
+       {
+         struct gdbarch *gdbarch = get_objfile_arch (objfile);
+         int i;
+         struct probe *probe;
+
+         for (i = 0;
+              VEC_iterate (probe_p,
+                           bp_objfile_data->exception_probes,
+                           i, probe);
+              ++i)
+           {
+             struct breakpoint *b;
+
+             b = create_internal_breakpoint (gdbarch, probe->address,
+                                             bp_exception_master,
+                                             &internal_breakpoint_ops);
+             b->addr_string = xstrdup ("-probe-stap libgcc:unwind");
+             b->enable_state = bp_disabled;
+           }
+
+         continue;
+       }
+
+      /* Otherwise, try the hook function.  */
+
       if (msym_not_found_p (bp_objfile_data->exception_msym))
        continue;
 
@@ -3341,6 +3464,10 @@ breakpoint_init_inferior (enum inf_context context)
           (gdb) tar rem :9999     # remote Windows gdbserver.
        */
 
+      case bp_step_resume:
+
+       /* Also remove step-resume breakpoints.  */
+
        delete_breakpoint (b);
        break;
 
@@ -3613,7 +3740,7 @@ breakpoint_thread_match (struct address_space *aspace, CORE_ADDR pc,
    in breakpoint.h.  */
 
 int
-ep_is_catchpoint (struct breakpoint *ep)
+is_catchpoint (struct breakpoint *ep)
 {
   return (ep->type == bp_catchpoint);
 }
@@ -5054,6 +5181,11 @@ bpstat_what (bpstat bs_head)
             PC of the former breakpoint.  */
          this_action = BPSTAT_WHAT_KEEP_CHECKING;
          break;
+
+       case bp_dprintf:
+         this_action = BPSTAT_WHAT_STOP_SILENT;
+         break;
+
        default:
          internal_error (__FILE__, __LINE__,
                          _("bpstat_what: unhandled bptype %d"), (int) bptype);
@@ -5255,10 +5387,10 @@ print_breakpoint_location (struct breakpoint *b,
     }
   else if (loc)
     {
-      struct ui_stream *stb = ui_out_stream_new (uiout);
-      struct cleanup *stb_chain = make_cleanup_ui_out_stream_delete (stb);
+      struct ui_file *stb = mem_fileopen ();
+      struct cleanup *stb_chain = make_cleanup_ui_file_delete (stb);
 
-      print_address_symbolic (loc->gdbarch, loc->address, stb->stream,
+      print_address_symbolic (loc->gdbarch, loc->address, stb,
                              demangle, "");
       ui_out_field_stream (uiout, "at", stb);
 
@@ -5318,6 +5450,7 @@ bptype_string (enum bptype type)
     {bp_tracepoint, "tracepoint"},
     {bp_fast_tracepoint, "fast tracepoint"},
     {bp_static_tracepoint, "static tracepoint"},
+    {bp_dprintf, "dprintf"},
     {bp_jit_event, "jit events"},
     {bp_gnu_ifunc_resolver, "STT_GNU_IFUNC resolver"},
     {bp_gnu_ifunc_resolver_return, "STT_GNU_IFUNC resolver return"},
@@ -5458,6 +5591,7 @@ print_one_breakpoint_location (struct breakpoint *b,
       case bp_tracepoint:
       case bp_fast_tracepoint:
       case bp_static_tracepoint:
+      case bp_dprintf:
       case bp_jit_event:
       case bp_gnu_ifunc_resolver:
       case bp_gnu_ifunc_resolver_return:
@@ -5578,7 +5712,7 @@ print_one_breakpoint_location (struct breakpoint *b,
   if (!part_of_multiple && b->hit_count)
     {
       /* FIXME should make an annotation for this.  */
-      if (ep_is_catchpoint (b))
+      if (is_catchpoint (b))
        ui_out_text (uiout, "\tcatchpoint");
       else if (is_tracepoint (b))
        ui_out_text (uiout, "\ttracepoint");
@@ -6320,6 +6454,7 @@ init_bp_location (struct bp_location *loc, const struct bp_location_ops *ops,
     case bp_exception_master:
     case bp_gnu_ifunc_resolver:
     case bp_gnu_ifunc_resolver_return:
+    case bp_dprintf:
       loc->loc_type = bp_loc_software_breakpoint;
       mark_breakpoint_location_modified (loc);
       break;
@@ -6462,9 +6597,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)
        {
@@ -6485,6 +6621,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;
            }
        }
 
@@ -6624,6 +6763,19 @@ delete_longjmp_breakpoint (int thread)
       }
 }
 
+void
+delete_longjmp_breakpoint_at_next_stop (int thread)
+{
+  struct breakpoint *b, *b_tmp;
+
+  ALL_BREAKPOINTS_SAFE (b, b_tmp)
+    if (b->type == bp_longjmp || b->type == bp_exception)
+      {
+       if (b->thread == thread)
+         b->disposition = disp_del_at_next_stop;
+      }
+}
+
 void
 enable_overlay_breakpoints (void)
 {
@@ -7307,7 +7459,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;
@@ -7356,6 +7507,8 @@ 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
@@ -7387,6 +7540,47 @@ dtor_catch_syscall (struct breakpoint *b)
   base_breakpoint_ops.dtor (b);
 }
 
+static const struct inferior_data *catch_syscall_inferior_data = NULL;
+
+struct catch_syscall_inferior_data
+{
+  /* We keep a count of the number of times the user has requested a
+     particular syscall to be tracked, and pass this information to the
+     target.  This lets capable targets implement filtering directly.  */
+
+  /* Number of times that "any" syscall is requested.  */
+  int any_syscall_count;
+
+  /* Count of each system call.  */
+  VEC(int) *syscalls_counts;
+
+  /* This counts all syscall catch requests, so we can readily determine
+     if any catching is necessary.  */
+  int total_syscalls_count;
+};
+
+static struct catch_syscall_inferior_data*
+get_catch_syscall_inferior_data (struct inferior *inf)
+{
+  struct catch_syscall_inferior_data *inf_data;
+
+  inf_data = inferior_data (inf, catch_syscall_inferior_data);
+  if (inf_data == NULL)
+    {
+      inf_data = XZALLOC (struct catch_syscall_inferior_data);
+      set_inferior_data (inf, catch_syscall_inferior_data, inf_data);
+    }
+
+  return inf_data;
+}
+
+static void
+catch_syscall_inferior_data_cleanup (struct inferior *inf, void *arg)
+{
+  xfree (arg);
+}
+
+
 /* Implement the "insert" breakpoint_ops method for syscall
    catchpoints.  */
 
@@ -7395,10 +7589,12 @@ insert_catch_syscall (struct bp_location *bl)
 {
   struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
   struct inferior *inf = current_inferior ();
+  struct catch_syscall_inferior_data *inf_data
+    = get_catch_syscall_inferior_data (inf);
 
-  ++inf->total_syscalls_count;
+  ++inf_data->total_syscalls_count;
   if (!c->syscalls_to_be_caught)
-    ++inf->any_syscall_count;
+    ++inf_data->any_syscall_count;
   else
     {
       int i, iter;
@@ -7409,28 +7605,31 @@ insert_catch_syscall (struct bp_location *bl)
        {
           int elem;
 
-         if (iter >= VEC_length (int, inf->syscalls_counts))
+         if (iter >= VEC_length (int, inf_data->syscalls_counts))
            {
-              int old_size = VEC_length (int, inf->syscalls_counts);
+              int old_size = VEC_length (int, inf_data->syscalls_counts);
               uintptr_t vec_addr_offset
                = old_size * ((uintptr_t) sizeof (int));
               uintptr_t vec_addr;
-              VEC_safe_grow (int, inf->syscalls_counts, iter + 1);
-              vec_addr = (uintptr_t) VEC_address (int, inf->syscalls_counts) +
-               vec_addr_offset;
+              VEC_safe_grow (int, inf_data->syscalls_counts, iter + 1);
+              vec_addr = ((uintptr_t) VEC_address (int,
+                                                 inf_data->syscalls_counts)
+                         + vec_addr_offset);
               memset ((void *) vec_addr, 0,
                       (iter + 1 - old_size) * sizeof (int));
            }
-          elem = VEC_index (int, inf->syscalls_counts, iter);
-          VEC_replace (int, inf->syscalls_counts, iter, ++elem);
+          elem = VEC_index (int, inf_data->syscalls_counts, iter);
+          VEC_replace (int, inf_data->syscalls_counts, iter, ++elem);
        }
     }
 
   return target_set_syscall_catchpoint (PIDGET (inferior_ptid),
-                                       inf->total_syscalls_count != 0,
-                                       inf->any_syscall_count,
-                                       VEC_length (int, inf->syscalls_counts),
-                                       VEC_address (int, inf->syscalls_counts));
+                                       inf_data->total_syscalls_count != 0,
+                                       inf_data->any_syscall_count,
+                                       VEC_length (int,
+                                                   inf_data->syscalls_counts),
+                                       VEC_address (int,
+                                                    inf_data->syscalls_counts));
 }
 
 /* Implement the "remove" breakpoint_ops method for syscall
@@ -7441,10 +7640,12 @@ remove_catch_syscall (struct bp_location *bl)
 {
   struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
   struct inferior *inf = current_inferior ();
+  struct catch_syscall_inferior_data *inf_data
+    = get_catch_syscall_inferior_data (inf);
 
-  --inf->total_syscalls_count;
+  --inf_data->total_syscalls_count;
   if (!c->syscalls_to_be_caught)
-    --inf->any_syscall_count;
+    --inf_data->any_syscall_count;
   else
     {
       int i, iter;
@@ -7454,20 +7655,21 @@ remove_catch_syscall (struct bp_location *bl)
            i++)
        {
           int elem;
-         if (iter >= VEC_length (int, inf->syscalls_counts))
+         if (iter >= VEC_length (int, inf_data->syscalls_counts))
            /* Shouldn't happen.  */
            continue;
-          elem = VEC_index (int, inf->syscalls_counts, iter);
-          VEC_replace (int, inf->syscalls_counts, iter, --elem);
+          elem = VEC_index (int, inf_data->syscalls_counts, iter);
+          VEC_replace (int, inf_data->syscalls_counts, iter, --elem);
         }
     }
 
   return target_set_syscall_catchpoint (PIDGET (inferior_ptid),
-                                       inf->total_syscalls_count != 0,
-                                       inf->any_syscall_count,
-                                       VEC_length (int, inf->syscalls_counts),
+                                       inf_data->total_syscalls_count != 0,
+                                       inf_data->any_syscall_count,
+                                       VEC_length (int,
+                                                   inf_data->syscalls_counts),
                                        VEC_address (int,
-                                                    inf->syscalls_counts));
+                                                    inf_data->syscalls_counts));
 }
 
 /* Implement the "breakpoint_hit" breakpoint_ops method for syscall
@@ -7524,7 +7726,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);
 
@@ -8052,6 +8253,7 @@ momentary_breakpoint_from_master (struct breakpoint *orig,
   copy->loc->address = orig->loc->address;
   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);
@@ -8137,6 +8339,7 @@ add_location_to_breakpoint (struct breakpoint *b,
   loc->requested_address = sal->pc;
   loc->address = adjusted_address;
   loc->pspace = sal->pspace;
+  loc->probe = sal->probe;
   gdb_assert (loc->pspace != NULL);
   loc->section = sal->section;
   loc->gdbarch = loc_gdbarch;
@@ -8192,7 +8395,122 @@ 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.  */
+
+static void
+update_dprintf_command_list (struct breakpoint *b)
+{
+  char *dprintf_args = b->extra_string;
+  char *printf_line = NULL;
+
+  if (!dprintf_args)
+    return;
+
+  dprintf_args = skip_spaces (dprintf_args);
+
+  /* Allow a comma, as it may have terminated a location, but don't
+     insist on it.  */
+  if (*dprintf_args == ',')
+    ++dprintf_args;
+  dprintf_args = skip_spaces (dprintf_args);
+
+  if (*dprintf_args != '"')
+    error (_("Bad format string, missing '\"'."));
+
+  if (strcmp (dprintf_style, "gdb") == 0)
+    printf_line = xstrprintf ("printf %s", dprintf_args);
+  else if (strcmp (dprintf_style, "call") == 0)
+    {
+      if (!dprintf_function)
+       error (_("No function supplied for dprintf call"));
+
+      if (dprintf_channel && strlen (dprintf_channel) > 0)
+       printf_line = xstrprintf ("call (void) %s (%s,%s)",
+                                 dprintf_function,
+                                 dprintf_channel,
+                                 dprintf_args);
+      else
+       printf_line = xstrprintf ("call (void) %s (%s)",
+                                 dprintf_function,
+                                 dprintf_args);
+    }
+  else
+    internal_error (__FILE__, __LINE__,
+                   _("Invalid dprintf style."));
+
+  /* Manufacture a printf/continue sequence.  */
+  if (printf_line)
+    {
+      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");
+
+      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->line = printf_line;
+
+      breakpoint_set_commands (b, printf_cmd_line);
+    }
+}
+
+/* Update all dprintf commands, making their command lists reflect
+   current style settings.  */
 
+static void
+update_dprintf_commands (char *args, int from_tty,
+                        struct cmd_list_element *c)
+{
+  struct breakpoint *b;
+
+  ALL_BREAKPOINTS (b)
+    {
+      if (b->type == bp_dprintf)
+       update_dprintf_command_list (b);
+    }
+}
 
 /* Create a breakpoint with SAL as location.  Use ADDR_STRING
    as textual description of the location, and COND_STRING
@@ -8202,10 +8520,12 @@ static void
 init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
                     struct symtabs_and_lines sals, char *addr_string,
                     char *filter, char *cond_string,
+                    char *extra_string,
                     enum bptype type, enum bpdisp disposition,
                     int thread, int task, int ignore_count,
                     const struct breakpoint_ops *ops, int from_tty,
-                    int enabled, int internal, int display_canonical)
+                    int enabled, int internal, unsigned flags,
+                    int display_canonical)
 {
   int i;
 
@@ -8245,12 +8565,16 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
          init_raw_breakpoint (b, gdbarch, sal, type, ops);
          b->thread = thread;
          b->task = task;
-  
+
          b->cond_string = cond_string;
+         b->extra_string = extra_string;
          b->ignore_count = ignore_count;
          b->enable_state = enabled ? bp_enabled : bp_disabled;
          b->disposition = disposition;
 
+         if ((flags & CREATE_BREAKPOINT_FLAGS_INSERTED) != 0)
+           b->loc->inserted = 1;
+
          if (type == bp_static_tracepoint)
            {
              struct tracepoint *t = (struct tracepoint *) b;
@@ -8294,6 +8618,8 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
       else
        {
          loc = add_location_to_breakpoint (b, &sal);
+         if ((flags & CREATE_BREAKPOINT_FLAGS_INSERTED) != 0)
+           loc->inserted = 1;
        }
 
       if (bp_loc_is_permanent (loc))
@@ -8304,9 +8630,21 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
          char *arg = b->cond_string;
          loc->cond = parse_exp_1 (&arg, 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
+        command line, otherwise it's an error.  */
+      if (type == bp_dprintf)
+       {
+         if (b->extra_string)
+           update_dprintf_command_list (b);
+         else
+           error (_("Format string required"));
        }
-    }   
+      else if (b->extra_string)
+       error (_("Garbage '%s' at end of command"), b->extra_string);
+    }
 
   b->display_canonical = display_canonical;
   if (addr_string)
@@ -8323,10 +8661,12 @@ static void
 create_breakpoint_sal (struct gdbarch *gdbarch,
                       struct symtabs_and_lines sals, char *addr_string,
                       char *filter, char *cond_string,
+                      char *extra_string,
                       enum bptype type, enum bpdisp disposition,
                       int thread, int task, int ignore_count,
                       const struct breakpoint_ops *ops, int from_tty,
-                      int enabled, int internal, int display_canonical)
+                      int enabled, int internal, unsigned flags,
+                      int display_canonical)
 {
   struct breakpoint *b;
   struct cleanup *old_chain;
@@ -8345,11 +8685,12 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
 
   init_breakpoint_sal (b, gdbarch,
                       sals, addr_string,
-                      filter, cond_string,
+                      filter, cond_string, extra_string,
                       type, disposition,
                       thread, task, ignore_count,
                       ops, from_tty,
-                      enabled, internal, display_canonical);
+                      enabled, internal, flags,
+                      display_canonical);
   discard_cleanups (old_chain);
 
   install_breakpoint (internal, b, 0);
@@ -8373,11 +8714,11 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
 static void
 create_breakpoints_sal (struct gdbarch *gdbarch,
                        struct linespec_result *canonical,
-                       char *cond_string,
+                       char *cond_string, char *extra_string,
                        enum bptype type, enum bpdisp disposition,
                        int thread, int task, int ignore_count,
                        const struct breakpoint_ops *ops, int from_tty,
-                       int enabled, int internal)
+                       int enabled, int internal, unsigned flags)
 {
   int i;
   struct linespec_sals *lsal;
@@ -8399,9 +8740,10 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
       create_breakpoint_sal (gdbarch, lsal->sals,
                             addr_string,
                             filter_string,
-                            cond_string, type, disposition,
+                            cond_string, extra_string,
+                            type, disposition,
                             thread, task, ignore_count, ops,
-                            from_tty, enabled, internal,
+                            from_tty, enabled, internal, flags,
                             canonical->special_display);
       discard_cleanups (inner);
     }
@@ -8534,9 +8876,11 @@ check_fast_tracepoint_sals (struct gdbarch *gdbarch,
    PC identifies the context at which the condition should be parsed.
    If no condition is found, *COND_STRING is set to NULL.
    If no thread is found, *THREAD is set to -1.  */
-static void 
-find_condition_and_thread (char *tok, CORE_ADDR pc, 
-                          char **cond_string, int *thread, int *task)
+
+static void
+find_condition_and_thread (char *tok, CORE_ADDR pc,
+                          char **cond_string, int *thread, int *task,
+                          char **rest)
 {
   *cond_string = NULL;
   *thread = -1;
@@ -8548,11 +8892,17 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
       char *cond_end = NULL;
 
       tok = skip_spaces (tok);
-      
+
+      if ((*tok == '"' || *tok == ',') && rest)
+       {
+         *rest = savestring (tok, strlen (tok));
+         return;
+       }
+
       end_tok = skip_to_space (tok);
-      
+
       toklen = end_tok - tok;
-      
+
       if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
        {
          struct expression *expr;
@@ -8561,13 +8911,12 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
          expr = parse_exp_1 (&tok, block_for_pc (pc), 0);
          xfree (expr);
          cond_end = tok;
-         *cond_string = savestring (cond_start, 
-                                    cond_end - cond_start);
+         *cond_string = savestring (cond_start, cond_end - cond_start);
        }
       else if (toklen >= 1 && strncmp (tok, "thread", toklen) == 0)
        {
          char *tmptok;
-         
+
          tok = end_tok + 1;
          tmptok = tok;
          *thread = strtol (tok, &tok, 0);
@@ -8588,6 +8937,11 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
          if (!valid_task_id (*task))
            error (_("Unknown task %d."), *task);
        }
+      else if (rest)
+       {
+         *rest = savestring (tok, strlen (tok));
+         tok += toklen;
+       }
       else
        error (_("Junk at end of arguments."));
     }
@@ -8600,8 +8954,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;
@@ -8655,13 +9007,15 @@ decode_static_tracepoint_spec (char **arg_p)
 
 int
 create_breakpoint (struct gdbarch *gdbarch,
-                  char *arg, char *cond_string, int thread,
+                  char *arg, char *cond_string,
+                  int thread, char *extra_string,
                   int parse_condition_and_thread,
                   int tempflag, enum bptype type_wanted,
                   int ignore_count,
                   enum auto_boolean pending_break_support,
                   const struct breakpoint_ops *ops,
-                  int from_tty, int enabled, int internal)
+                  int from_tty, int enabled, int internal,
+                  unsigned flags)
 {
   volatile struct gdb_exception e;
   char *copy_arg = NULL;
@@ -8669,7 +9023,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;
@@ -8776,16 +9129,22 @@ create_breakpoint (struct gdbarch *gdbarch,
 
       if (parse_condition_and_thread)
         {
+           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.  */
             cond_string = NULL;
             thread = -1;
+           rest = NULL;
             find_condition_and_thread (arg, lsal->sals.sals[0].pc, &cond_string,
-                                       &thread, &task);
+                                       &thread, &task, &rest);
             if (cond_string)
                 make_cleanup (xfree, cond_string);
+           if (rest)
+             make_cleanup (xfree, rest);
+           if (rest)
+             extra_string = rest;
         }
       else
         {
@@ -8795,13 +9154,19 @@ create_breakpoint (struct gdbarch *gdbarch,
                 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,
-                                  cond_string, type_wanted,
+                                  cond_string, extra_string, type_wanted,
                                   tempflag ? disp_del : disp_donttouch,
                                   thread, task, ignore_count, ops,
-                                  from_tty, enabled, internal);
+                                  from_tty, enabled, internal, flags);
     }
   else
     {
@@ -8823,6 +9188,7 @@ create_breakpoint (struct gdbarch *gdbarch,
 
       b->addr_string = copy_arg;
       b->cond_string = NULL;
+      b->extra_string = NULL;
       b->ignore_count = ignore_count;
       b->disposition = tempflag ? disp_del : disp_donttouch;
       b->condition_not_parsed = 1;
@@ -8867,17 +9233,26 @@ break_command_1 (char *arg, int flag, int from_tty)
   enum bptype type_wanted = (flag & BP_HARDWAREFLAG
                             ? bp_hardware_breakpoint
                             : bp_breakpoint);
+  struct breakpoint_ops *ops;
+  const char *arg_cp = arg;
+
+  /* Matching breakpoints on probes.  */
+  if (arg && probe_linespec_to_ops (&arg_cp) != NULL)
+    ops = &bkpt_probe_breakpoint_ops;
+  else
+    ops = &bkpt_breakpoint_ops;
 
   create_breakpoint (get_current_arch (),
                     arg,
-                    NULL, 0, 1 /* parse arg */,
+                    NULL, 0, NULL, 1 /* parse arg */,
                     tempflag, type_wanted,
                     0 /* Ignore count */,
                     pending_break_support,
-                    &bkpt_breakpoint_ops,
+                    ops,
                     from_tty,
                     1 /* enabled */,
-                    0 /* internal */);
+                    0 /* internal */,
+                    0);
 }
 
 /* Helper function for break_command_1 and disassemble_command.  */
@@ -9034,6 +9409,29 @@ stopat_command (char *arg, int from_tty)
     break_command_1 (arg, 0, from_tty);
 }
 
+void dprintf_command (char *arg, int from_tty);
+
+/* The dynamic printf command is mostly like a regular breakpoint, but
+   with a prewired command list consisting of a single output command,
+   built from extra arguments supplied on the dprintf command
+   line.  */
+
+void
+dprintf_command (char *arg, int from_tty)
+{
+  create_breakpoint (get_current_arch (),
+                    arg,
+                    NULL, 0, NULL, 1 /* parse arg */,
+                    0, bp_dprintf,
+                    0 /* Ignore count */,
+                    pending_break_support,
+                    &dprintf_breakpoint_ops,
+                    from_tty,
+                    1 /* enabled */,
+                    0 /* internal */,
+                    0);
+}
+
 /* Implement the "breakpoint_hit" breakpoint_ops method for
    ranged breakpoints.  */
 
@@ -9044,7 +9442,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,
@@ -9126,8 +9524,8 @@ print_one_detail_ranged_breakpoint (const struct breakpoint *b,
 {
   CORE_ADDR address_start, address_end;
   struct bp_location *bl = b->loc;
-  struct ui_stream *stb = ui_out_stream_new (uiout);
-  struct cleanup *cleanup = make_cleanup_ui_out_stream_delete (stb);
+  struct ui_file *stb = mem_fileopen ();
+  struct cleanup *cleanup = make_cleanup_ui_file_delete (stb);
 
   gdb_assert (bl);
 
@@ -9135,7 +9533,7 @@ print_one_detail_ranged_breakpoint (const struct breakpoint *b,
   address_end = address_start + bl->length - 1;
 
   ui_out_text (uiout, "\taddress range: ");
-  fprintf_unfiltered (stb->stream, "[%s, %s]",
+  fprintf_unfiltered (stb, "[%s, %s]",
                      print_core_address (bl->gdbarch, address_start),
                      print_core_address (bl->gdbarch, address_end));
   ui_out_field_stream (uiout, "addr", stb);
@@ -9570,7 +9968,7 @@ print_it_watchpoint (bpstat bs)
   struct cleanup *old_chain;
   struct breakpoint *b;
   const struct bp_location *bl;
-  struct ui_stream *stb;
+  struct ui_file *stb;
   enum print_stop_action result;
   struct watchpoint *w;
   struct ui_out *uiout = current_uiout;
@@ -9581,8 +9979,8 @@ print_it_watchpoint (bpstat bs)
   b = bs->breakpoint_at;
   w = (struct watchpoint *) b;
 
-  stb = ui_out_stream_new (uiout);
-  old_chain = make_cleanup_ui_out_stream_delete (stb);
+  stb = mem_fileopen ();
+  old_chain = make_cleanup_ui_file_delete (stb);
 
   switch (b->type)
     {
@@ -9596,10 +9994,10 @@ print_it_watchpoint (bpstat bs)
       mention (b);
       make_cleanup_ui_out_tuple_begin_end (uiout, "value");
       ui_out_text (uiout, "\nOld value = ");
-      watchpoint_value_print (bs->old_val, stb->stream);
+      watchpoint_value_print (bs->old_val, stb);
       ui_out_field_stream (uiout, "old", stb);
       ui_out_text (uiout, "\nNew value = ");
-      watchpoint_value_print (w->val, stb->stream);
+      watchpoint_value_print (w->val, stb);
       ui_out_field_stream (uiout, "new", stb);
       ui_out_text (uiout, "\n");
       /* More than one watchpoint may have been triggered.  */
@@ -9614,7 +10012,7 @@ print_it_watchpoint (bpstat bs)
       mention (b);
       make_cleanup_ui_out_tuple_begin_end (uiout, "value");
       ui_out_text (uiout, "\nValue = ");
-      watchpoint_value_print (w->val, stb->stream);
+      watchpoint_value_print (w->val, stb);
       ui_out_field_stream (uiout, "value", stb);
       ui_out_text (uiout, "\n");
       result = PRINT_UNKNOWN;
@@ -9631,7 +10029,7 @@ print_it_watchpoint (bpstat bs)
          mention (b);
          make_cleanup_ui_out_tuple_begin_end (uiout, "value");
          ui_out_text (uiout, "\nOld value = ");
-         watchpoint_value_print (bs->old_val, stb->stream);
+         watchpoint_value_print (bs->old_val, stb);
          ui_out_field_stream (uiout, "old", stb);
          ui_out_text (uiout, "\nNew value = ");
        }
@@ -9645,7 +10043,7 @@ print_it_watchpoint (bpstat bs)
          make_cleanup_ui_out_tuple_begin_end (uiout, "value");
          ui_out_text (uiout, "\nValue = ");
        }
-      watchpoint_value_print (w->val, stb->stream);
+      watchpoint_value_print (w->val, stb);
       ui_out_field_stream (uiout, "new", stb);
       ui_out_text (uiout, "\n");
       result = PRINT_UNKNOWN;
@@ -10493,7 +10891,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
@@ -10745,14 +11143,15 @@ handle_gnu_v3_exceptions (int tempflag, char *cond_string,
     trigger_func_name = "__cxa_throw";
 
   create_breakpoint (get_current_arch (),
-                    trigger_func_name, cond_string, -1,
+                    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 /* internal */,
+                    0);
 
   return 1;
 }
@@ -11973,13 +12372,14 @@ 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,
                                        enum bpdisp disposition,
                                        int thread,
                                        int task, int ignore_count,
                                        const struct breakpoint_ops *o,
                                        int from_tty, int enabled,
-                                       int internal)
+                                       int internal, unsigned flags)
 {
   internal_error_pure_virtual_called ();
 }
@@ -12056,7 +12456,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,
@@ -12135,6 +12535,9 @@ bkpt_print_mention (struct breakpoint *b)
     case bp_hardware_breakpoint:
       printf_filtered (_("Hardware assisted breakpoint %d"), b->number);
       break;
+    case bp_dprintf:
+      printf_filtered (_("Dprintf %d"), b->number);
+      break;
     }
 
   say_where (b);
@@ -12175,19 +12578,21 @@ 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,
                             enum bpdisp disposition,
                             int thread,
                             int task, int ignore_count,
                             const struct breakpoint_ops *ops,
                             int from_tty, int enabled,
-                            int internal)
+                            int internal, unsigned flags)
 {
   create_breakpoints_sal_default (gdbarch, canonical, lsal,
-                                 cond_string, type_wanted,
+                                 cond_string, extra_string,
+                                 type_wanted,
                                  disposition, thread, task,
                                  ignore_count, ops, from_tty,
-                                 enabled, internal);
+                                 enabled, internal, flags);
 }
 
 static void
@@ -12346,6 +12751,57 @@ momentary_bkpt_print_mention (struct breakpoint *b)
   /* Nothing to mention.  These breakpoints are internal.  */
 }
 
+/* Specific methods for probe breakpoints.  */
+
+static int
+bkpt_probe_insert_location (struct bp_location *bl)
+{
+  int v = bkpt_insert_location (bl);
+
+  if (v == 0)
+    {
+      /* The insertion was successful, now let's set the probe's semaphore
+        if needed.  */
+      bl->probe->pops->set_semaphore (bl->probe, bl->gdbarch);
+    }
+
+  return v;
+}
+
+static int
+bkpt_probe_remove_location (struct bp_location *bl)
+{
+  /* Let's clear the semaphore before removing the location.  */
+  bl->probe->pops->clear_semaphore (bl->probe, bl->gdbarch);
+
+  return bkpt_remove_location (bl);
+}
+
+static void
+bkpt_probe_create_sals_from_address (char **arg,
+                                    struct linespec_result *canonical,
+                                    enum bptype type_wanted,
+                                    char *addr_start, char **copy_arg)
+{
+  struct linespec_sals lsal;
+
+  lsal.sals = parse_probes (arg, canonical);
+
+  *copy_arg = xstrdup (canonical->addr_string);
+  lsal.canonical = xstrdup (*copy_arg);
+
+  VEC_safe_push (linespec_sals, canonical->sals, &lsal);
+}
+
+static void
+bkpt_probe_decode_linespec (struct breakpoint *b, char **s,
+                           struct symtabs_and_lines *sals)
+{
+  *sals = parse_probes (s, NULL);
+  if (!sals->sals)
+    error (_("probe not found"));
+}
+
 /* The breakpoint_ops structure to be used in tracepoints.  */
 
 static void
@@ -12445,19 +12901,21 @@ 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,
                                   enum bpdisp disposition,
                                   int thread,
                                   int task, int ignore_count,
                                   const struct breakpoint_ops *ops,
                                   int from_tty, int enabled,
-                                  int internal)
+                                  int internal, unsigned flags)
 {
   create_breakpoints_sal_default (gdbarch, canonical, lsal,
-                                 cond_string, type_wanted,
+                                 cond_string, extra_string,
+                                 type_wanted,
                                  disposition, thread, task,
                                  ignore_count, ops, from_tty,
-                                 enabled, internal);
+                                 enabled, internal, flags);
 }
 
 static void
@@ -12469,6 +12927,30 @@ tracepoint_decode_linespec (struct breakpoint *b, char **s,
 
 struct breakpoint_ops tracepoint_breakpoint_ops;
 
+/* The breakpoint_ops structure to be use on tracepoints placed in a
+   static probe.  */
+
+static void
+tracepoint_probe_create_sals_from_address (char **arg,
+                                          struct linespec_result *canonical,
+                                          enum bptype type_wanted,
+                                          char *addr_start, char **copy_arg)
+{
+  /* We use the same method for breakpoint on probes.  */
+  bkpt_probe_create_sals_from_address (arg, canonical, type_wanted,
+                                      addr_start, copy_arg);
+}
+
+static void
+tracepoint_probe_decode_linespec (struct breakpoint *b, char **s,
+                                 struct symtabs_and_lines *sals)
+{
+  /* We use the same method for breakpoint on probes.  */
+  bkpt_probe_decode_linespec (b, s, sals);
+}
+
+static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
+
 /* The breakpoint_ops structure to be used on static tracepoints with
    markers (`-m').  */
 
@@ -12494,13 +12976,14 @@ 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,
                                      enum bpdisp disposition,
                                      int thread,
                                      int task, int ignore_count,
                                      const struct breakpoint_ops *ops,
                                      int from_tty, int enabled,
-                                     int internal)
+                                     int internal, unsigned flags)
 {
   int i;
 
@@ -12527,9 +13010,10 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
       tp = XCNEW (struct tracepoint);
       init_breakpoint_sal (&tp->base, gdbarch, expanded,
                           addr_string, NULL,
-                          cond_string, type_wanted, disposition,
+                          cond_string, extra_string,
+                          type_wanted, disposition,
                           thread, task, ignore_count, ops,
-                          from_tty, enabled, internal,
+                          from_tty, enabled, internal, flags,
                           canonical->special_display);
       /* Given that its possible to have multiple markers with
         the same string id, if the user is creating a static
@@ -12850,7 +13334,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)
@@ -13154,13 +13637,17 @@ addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
          char *cond_string = 0;
          int thread = -1;
          int task = 0;
+         char *extra_string = NULL;
 
          find_condition_and_thread (s, sals.sals[0].pc,
-                                    &cond_string, &thread, &task);
+                                    &cond_string, &thread, &task,
+                                    &extra_string);
          if (cond_string)
            b->cond_string = cond_string;
          b->thread = thread;
          b->task = task;
+         if (extra_string)
+           b->extra_string = extra_string;
          b->condition_not_parsed = 0;
        }
 
@@ -13228,18 +13715,20 @@ 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,
                                enum bpdisp disposition,
                                int thread,
                                int task, int ignore_count,
                                const struct breakpoint_ops *ops,
                                int from_tty, int enabled,
-                               int internal)
+                               int internal, unsigned flags)
 {
   create_breakpoints_sal (gdbarch, canonical, cond_string,
+                         extra_string,
                          type_wanted, disposition,
                          thread, task, ignore_count, ops, from_tty,
-                         enabled, internal);
+                         enabled, internal, flags);
 }
 
 /* Decode the line represented by S by calling decode_line_full.  This is the
@@ -14042,9 +14531,10 @@ is_syscall_catchpoint_enabled (struct breakpoint *bp)
 int
 catch_syscall_enabled (void)
 {
-  struct inferior *inf = current_inferior ();
+  struct catch_syscall_inferior_data *inf_data
+    = get_catch_syscall_inferior_data (current_inferior ());
 
-  return inf->total_syscalls_count != 0;
+  return inf_data->total_syscalls_count != 0;
 }
 
 int
@@ -14099,17 +14589,25 @@ set_tracepoint_count (int num)
 static void
 trace_command (char *arg, int from_tty)
 {
+  struct breakpoint_ops *ops;
+  const char *arg_cp = arg;
+
+  if (arg && probe_linespec_to_ops (&arg_cp))
+    ops = &tracepoint_probe_breakpoint_ops;
+  else
+    ops = &tracepoint_breakpoint_ops;
+
   if (create_breakpoint (get_current_arch (),
                         arg,
-                        NULL, 0, 1 /* parse arg */,
+                        NULL, 0, NULL, 1 /* parse arg */,
                         0 /* tempflag */,
                         bp_tracepoint /* type_wanted */,
                         0 /* Ignore count */,
                         pending_break_support,
-                        &tracepoint_breakpoint_ops,
+                        ops,
                         from_tty,
                         1 /* enabled */,
-                        0 /* internal */))
+                        0 /* internal */, 0))
     set_tracepoint_count (breakpoint_count);
 }
 
@@ -14118,7 +14616,7 @@ ftrace_command (char *arg, int from_tty)
 {
   if (create_breakpoint (get_current_arch (),
                         arg,
-                        NULL, 0, 1 /* parse arg */,
+                        NULL, 0, NULL, 1 /* parse arg */,
                         0 /* tempflag */,
                         bp_fast_tracepoint /* type_wanted */,
                         0 /* Ignore count */,
@@ -14126,7 +14624,7 @@ ftrace_command (char *arg, int from_tty)
                         &tracepoint_breakpoint_ops,
                         from_tty,
                         1 /* enabled */,
-                        0 /* internal */))
+                        0 /* internal */, 0))
     set_tracepoint_count (breakpoint_count);
 }
 
@@ -14146,7 +14644,7 @@ strace_command (char *arg, int from_tty)
 
   if (create_breakpoint (get_current_arch (),
                         arg,
-                        NULL, 0, 1 /* parse arg */,
+                        NULL, 0, NULL, 1 /* parse arg */,
                         0 /* tempflag */,
                         bp_static_tracepoint /* type_wanted */,
                         0 /* Ignore count */,
@@ -14154,7 +14652,7 @@ strace_command (char *arg, int from_tty)
                         ops,
                         from_tty,
                         1 /* enabled */,
-                        0 /* internal */))
+                        0 /* internal */, 0))
     set_tracepoint_count (breakpoint_count);
 }
 
@@ -14211,7 +14709,8 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
 
   if (!create_breakpoint (get_current_arch (),
                          addr_str,
-                         utp->cond_string, -1, 0 /* parse cond/thread */,
+                         utp->cond_string, -1, NULL,
+                         0 /* parse cond/thread */,
                          0 /* tempflag */,
                          utp->type /* type_wanted */,
                          0 /* Ignore count */,
@@ -14219,7 +14718,8 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
                          &tracepoint_breakpoint_ops,
                          0 /* from_tty */,
                          utp->enabled /* enabled */,
-                         0 /* internal */))
+                         0 /* internal */,
+                         CREATE_BREAKPOINT_FLAGS_INSERTED))
     return NULL;
 
   set_tracepoint_count (breakpoint_count);
@@ -14709,9 +15209,12 @@ add_catch_command (char *name, char *docstring,
 static void
 clear_syscall_counts (struct inferior *inf)
 {
-  inf->total_syscalls_count = 0;
-  inf->any_syscall_count = 0;
-  VEC_free (int, inf->syscalls_counts);
+  struct catch_syscall_inferior_data *inf_data
+    = get_catch_syscall_inferior_data (inf);
+
+  inf_data->total_syscalls_count = 0;
+  inf_data->any_syscall_count = 0;
+  VEC_free (int, inf_data->syscalls_counts);
 }
 
 static void
@@ -14837,6 +15340,14 @@ initialize_breakpoint_ops (void)
   ops->print_it = momentary_bkpt_print_it;
   ops->print_mention = momentary_bkpt_print_mention;
 
+  /* Probe breakpoints.  */
+  ops = &bkpt_probe_breakpoint_ops;
+  *ops = bkpt_breakpoint_ops;
+  ops->insert_location = bkpt_probe_insert_location;
+  ops->remove_location = bkpt_probe_remove_location;
+  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;
@@ -14884,6 +15395,12 @@ initialize_breakpoint_ops (void)
   ops->create_breakpoints_sal = tracepoint_create_breakpoints_sal;
   ops->decode_linespec = tracepoint_decode_linespec;
 
+  /* Probe tracepoints.  */
+  ops = &tracepoint_probe_breakpoint_ops;
+  *ops = tracepoint_breakpoint_ops;
+  ops->create_sals_from_address = tracepoint_probe_create_sals_from_address;
+  ops->decode_linespec = tracepoint_probe_decode_linespec;
+
   /* Static tracepoints with marker (`-m').  */
   ops = &strace_marker_breakpoint_ops;
   *ops = tracepoint_breakpoint_ops;
@@ -14949,6 +15466,14 @@ initialize_breakpoint_ops (void)
   ops->print_one = print_one_catch_solib;
   ops->print_mention = print_mention_catch_solib;
   ops->print_recreate = print_recreate_catch_solib;
+
+  ops = &dprintf_breakpoint_ops;
+  *ops = bkpt_base_breakpoint_ops;
+  ops->re_set = bkpt_re_set;
+  ops->resources_needed = bkpt_resources_needed;
+  ops->print_it = bkpt_print_it;
+  ops->print_mention = bkpt_print_mention;
+  ops->print_recreate = bkpt_print_recreate;
 }
 
 void
@@ -14962,7 +15487,11 @@ _initialize_breakpoint (void)
   observer_attach_inferior_exit (clear_syscall_counts);
   observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
 
-  breakpoint_objfile_key = register_objfile_data ();
+  breakpoint_objfile_key
+    = register_objfile_data_with_cleanup (NULL, free_breakpoint_probes);
+
+  catch_syscall_inferior_data
+    = register_inferior_data_with_cleanup (catch_syscall_inferior_data_cleanup);
 
   breakpoint_chain = 0;
   /* Don't bother to call set_breakpoint_count.  $bpnum isn't useful
@@ -15499,7 +16028,7 @@ inferior in all-stop mode, gdb behaves as if always-inserted mode is off."),
                        &condition_evaluation_mode_1, _("\
 Set mode of breakpoint condition evaluation."), _("\
 Show mode of breakpoint condition evaluation."), _("\
-When this is set to \"gdb\", breakpoint conditions will be\n\
+When this is set to \"host\", breakpoint conditions will be\n\
 evaluated on the host's side by GDB.  When it is set to \"target\",\n\
 breakpoint conditions will be downloaded to the target (if the target\n\
 supports such feature) and conditions will be evaluated on the target's side.\n\
@@ -15527,6 +16056,44 @@ The breakpoint will stop execution of the inferior whenever it executes\n\
 an instruction at any address within the [START-LOCATION, END-LOCATION]\n\
 range (including START-LOCATION and END-LOCATION)."));
 
+  c = add_com ("dprintf", class_breakpoint, dprintf_command, _("\
+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\
+"));
+  set_cmd_completer (c, location_completer);
+
+  add_setshow_enum_cmd ("dprintf-style", class_support,
+                       dprintf_style_enums, &dprintf_style, _("\
+Set the style of usage for dynamic printf."), _("\
+Show the style of usage for dynamic printf."), _("\
+This setting chooses how GDB will do a dynamic printf.\n\
+If the value is \"gdb\", then the printing is done by GDB to its own\n\
+console, as with the \"printf\" command.\n\
+If the value is \"call\", the print is done by calling a function in your\n\
+program; by default printf(), but you can choose a different function or\n\
+output stream by setting dprintf-function and dprintf-channel."),
+                       update_dprintf_commands, NULL,
+                       &setlist, &showlist);
+
+  dprintf_function = xstrdup ("printf");
+  add_setshow_string_cmd ("dprintf-function", class_support,
+                         &dprintf_function, _("\
+Set the function to use for dynamic printf"), _("\
+Show the function to use for dynamic printf"), NULL,
+                         update_dprintf_commands, NULL,
+                         &setlist, &showlist);
+
+  dprintf_channel = xstrdup ("");
+  add_setshow_string_cmd ("dprintf-channel", class_support,
+                         &dprintf_channel, _("\
+Set the channel to use for dynamic printf"), _("\
+Show the channel to use for dynamic printf"), NULL,
+                         update_dprintf_commands, NULL,
+                         &setlist, &showlist);
+
   automatic_hardware_breakpoints = 1;
 
   observer_attach_about_to_proceed (breakpoint_about_to_proceed);
This page took 0.065741 seconds and 4 git commands to generate.