Add support for enabling and disabling tracepoints while a trace
authorKwok Yeung <kcy@sourceware.org>
Thu, 12 May 2011 12:09:17 +0000 (12:09 +0000)
committerKwok Yeung <kcy@sourceware.org>
Thu, 12 May 2011 12:09:17 +0000 (12:09 +0000)
experiment is still running.

gdb/
* breakpoint.c (disable_breakpoint): Disable all locations
associated with a tracepoint on target if a trace experiment is
running.
(disable_command): Disable a specific tracepoint location on target if
a trace experiment is running.
(do_enable_breakpoint): Enable all locations associated with a
tracepoint on target if a trace experiment is running.
(enable_command) Enable a specific tracepoint location on target if a
trace experiment is running.
* target.c (update_current_target): Add INHERIT and de_fault clauses for
to_supports_enable_disable_tracepoint, to_enable_tracepoint and
to_disable_tracepoint.
* target.h: Add declaration of struct bp_location.
(struct target_ops): Add new functions
to_supports_enable_disable_tracepoint, to_enable_tracepoint and
to_disable_tracepoint to target operations.
(target_supports_enable_disable_tracepoint): New macro.
(target_enable_tracepoint): New macro.
(target_disable_tracepoint): New macro.
* remote.c (struct remote_state): Add new field.
(remote_enable_disable_tracepoint_feature): New.
(remote_protocol_features): Add new entry.
(remote_supports_enable_disable_tracepoint): New.
(remote_enable_tracepoint): New.
(remote_disable_tracepoint): New.
(init_remote_ops): Add remote_enable_tracepoint,
remote_disable_tracepoint and remote_supports_enable_disable_tracepoint
to remote operations.
* tracepoint.c (start_tracing): Allow tracing to start without any
tracepoints enabled with just a warning if they can be re-enabled
later.
* NEWS: Add news item for the new behaviour of the enable and disable
GDB commands when applied to tracepoints.
Add news items for the new remote packets QTEnable and QTDisable.

gdb/doc/
* gdb.texinfo: Document change in the behaviour of the enable and
disable GDB commands when applied to tracepoints.
Document the EnableDisableTracepoints remote stub feature.
Document QTEnable and QTDisable in the list of tracepoint packets.

gdb/gdbserver/
* server.c (handle_query): Add EnableDisableTracepoints to the list
of supported features.
* tracepoint.c (clear_installed_tracepoints): Uninstall disabled
tracepoints.
(cmd_qtenable_disable): New.
(cmd_qtstart): Install tracepoints even if disabled.
(handle_tracepoint_general_set): Add call to cmd_qtenable_disable on
receiving a QTEnable or QTDisable packet.
(gdb_collect): Skip data collection if fast tracepoint is disabled.
(ust_marker_to_static_tracepoint): Do not ignore disabled static
tracepoints.
(gdb_probe): Skip data collection if static tracepoint is disabled.

12 files changed:
gdb/ChangeLog
gdb/NEWS
gdb/breakpoint.c
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/gdbserver/ChangeLog
gdb/gdbserver/server.c
gdb/gdbserver/tracepoint.c
gdb/remote.c
gdb/target.c
gdb/target.h
gdb/tracepoint.c

index 4a9cccfe76af2d66b1344f6f2dce0ed8f5403c01..56d74fc148fcbef2d389fb5614469baa6515c1a9 100644 (file)
@@ -1,3 +1,40 @@
+2011-05-12  Kwok Cheung Yeung  <kcy@codesourcery.com>
+
+       * breakpoint.c (disable_breakpoint): Disable all locations
+       associated with a tracepoint on target if a trace experiment is
+       running.
+       (disable_command): Disable a specific tracepoint location on target if
+       a trace experiment is running.
+       (do_enable_breakpoint): Enable all locations associated with a
+       tracepoint on target if a trace experiment is running.
+       (enable_command) Enable a specific tracepoint location on target if a
+       trace experiment is running.
+       * target.c (update_current_target): Add INHERIT and de_fault clauses for
+       to_supports_enable_disable_tracepoint, to_enable_tracepoint and
+       to_disable_tracepoint.
+       * target.h: Add declaration of struct bp_location.
+       (struct target_ops): Add new functions
+       to_supports_enable_disable_tracepoint, to_enable_tracepoint and
+       to_disable_tracepoint to target operations.
+       (target_supports_enable_disable_tracepoint): New macro.
+       (target_enable_tracepoint): New macro.
+       (target_disable_tracepoint): New macro.
+       * remote.c (struct remote_state): Add new field.
+       (remote_enable_disable_tracepoint_feature): New.
+       (remote_protocol_features): Add new entry.
+       (remote_supports_enable_disable_tracepoint): New.
+       (remote_enable_tracepoint): New.
+       (remote_disable_tracepoint): New.
+       (init_remote_ops): Add remote_enable_tracepoint,
+       remote_disable_tracepoint and remote_supports_enable_disable_tracepoint
+       to remote operations.
+       * tracepoint.c (start_tracing): Allow tracing to start without any
+       tracepoints enabled with just a warning if they can be re-enabled
+       later.
+       * NEWS: Add news item for the new behaviour of the enable and disable
+       GDB commands when applied to tracepoints.
+       Add news items for the new remote packets QTEnable and QTDisable.
+
 2011-05-11  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * config.in: Regenerate.
index e73529328912f61035e81b0569e5230f31f62100..e749015fda9c086a47c9a83bae63cfe0ca54307e 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -27,6 +27,23 @@ watch EXPRESSION mask MASK_VALUE
   The watch command now supports the mask argument which allows creation
   of masked watchpoints, if the current architecture supports this feature.
 
+* Tracepoints can now be enabled and disabled at any time after a trace
+  experiment has been started using the standard "enable" and "disable"
+  commands.  It is now possible to start a trace experiment with no enabled
+  tracepoints; GDB will display a warning, but will allow the experiment to
+  begin, assuming that tracepoints will be enabled as needed while the trace
+  is running.
+
+* New remote packets
+
+QTEnable
+  
+  Dynamically enable a tracepoint in a started trace experiment.
+
+QTDisable
+
+  Dynamically disable a tracepoint in a started trace experiment.
+
 *** Changes in GDB 7.3
 
 * GDB has a new command: "thread find [REGEXP]".
index e582c36c8a4956705213417b591fc63b711a4598..9ce3806baade3efd4421a629778e3671f10bba2a 100644 (file)
@@ -11685,6 +11685,15 @@ disable_breakpoint (struct breakpoint *bpt)
 
   bpt->enable_state = bp_disabled;
 
+  if (target_supports_enable_disable_tracepoint ()
+      && current_trace_status ()->running && is_tracepoint (bpt))
+    {
+      struct bp_location *location;
+     
+      for (location = bpt->loc; location; location = location->next)
+       target_disable_tracepoint (location);
+    }
+
   update_global_location_list (0);
 
   observer_notify_breakpoint_modified (bpt);
@@ -11714,7 +11723,13 @@ disable_command (char *args, int from_tty)
     {
       struct bp_location *loc = find_location_by_number (args);
       if (loc)
-       loc->enabled = 0;
+       {
+         loc->enabled = 0;
+         if (target_supports_enable_disable_tracepoint ()
+             && current_trace_status ()->running && loc->owner
+             && is_tracepoint (loc->owner))
+           target_disable_tracepoint (loc);
+       }
       update_global_location_list (0);
     }
   else
@@ -11762,6 +11777,16 @@ do_enable_breakpoint (struct breakpoint *bpt, enum bpdisp disposition)
 
   if (bpt->enable_state != bp_permanent)
     bpt->enable_state = bp_enabled;
+
+  if (target_supports_enable_disable_tracepoint ()
+      && current_trace_status ()->running && is_tracepoint (bpt))
+    {
+      struct bp_location *location;
+
+      for (location = bpt->loc; location; location = location->next)
+       target_enable_tracepoint (location);
+    }
+
   bpt->disposition = disposition;
   update_global_location_list (1);
   breakpoints_changed ();
@@ -11804,7 +11829,13 @@ enable_command (char *args, int from_tty)
     {
       struct bp_location *loc = find_location_by_number (args);
       if (loc)
-       loc->enabled = 1;
+       {
+         loc->enabled = 1;
+         if (target_supports_enable_disable_tracepoint ()
+             && current_trace_status ()->running && loc->owner
+             && is_tracepoint (loc->owner))
+           target_enable_tracepoint (loc);
+       }
       update_global_location_list (1);
     }
   else
index 1a987ef7df93d626e41faa387d3ce96e84e923fd..40f93eef0910cc8d4834beba83dfea22198232d7 100644 (file)
@@ -1,3 +1,10 @@
+2011-05-12  Kwok Cheung Yeung  <kcy@codesourcery.com>
+
+       * gdb.texinfo: Document change in the behaviour of the enable and
+       disable GDB commands when applied to tracepoints.
+       Document the EnableDisableTracepoints remote stub feature.
+       Document QTEnable and QTDisable in the list of tracepoint packets.
+
 2011-05-11  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * Makefile.in (GDB_DOC_SOURCE_INCLUDES): Rename inc-hist.texinfo to
index da2c784c7019aa61bfcce689f6f01a9883933eb7..67436dd56f83ae5186e6f1164e498237b0f4fe9e 100644 (file)
@@ -10026,14 +10026,20 @@ These commands are deprecated; they are equivalent to plain @code{disable} and @
 @item disable tracepoint @r{[}@var{num}@r{]}
 Disable tracepoint @var{num}, or all tracepoints if no argument
 @var{num} is given.  A disabled tracepoint will have no effect during
-the next trace experiment, but it is not forgotten.  You can re-enable
+a trace experiment, but it is not forgotten.  You can re-enable
 a disabled tracepoint using the @code{enable tracepoint} command.
+If the command is issued during a trace experiment and the debug target
+has support for disabling tracepoints during a trace experiment, then the
+change will be effective immediately.  Otherwise, it will be applied to the
+next trace experiment.
 
 @kindex enable tracepoint
 @item enable tracepoint @r{[}@var{num}@r{]}
-Enable tracepoint @var{num}, or all tracepoints.  The enabled
-tracepoints will become effective the next time a trace experiment is
-run.
+Enable tracepoint @var{num}, or all tracepoints.  If this command is
+issued during a trace experiment and the debug target supports enabling
+tracepoints during a trace experiment, then the enabled tracepoints will
+become effective immediately.  Otherwise, they will become effective the
+next time a trace experiment is run.
 @end table
 
 @node Tracepoint Passcounts
@@ -33627,6 +33633,11 @@ These are the currently defined stub features and their properties:
 @tab @samp{-}
 @tab No
 
+@item @samp{EnableDisableTracepoints}
+@tab No
+@tab @samp{-}
+@tab No
+
 @end multitable
 
 These are the currently defined stub features, in more detail:
@@ -33739,6 +33750,11 @@ The remote stub understands the @samp{QAllow} packet.
 @cindex static tracepoints, in remote protocol
 The remote stub supports static tracepoints.
 
+@item EnableDisableTracepoints
+The remote stub supports the @samp{QTEnable} (@pxref{QTEnable}) and
+@samp{QTDisable} (@pxref{QTDisable}) packets that allow tracepoints
+to be enabled and disabled while a trace experiment is running.
+
 @end table
 
 @item qSymbol::
@@ -33819,6 +33835,8 @@ packets.)
 @item qTsV
 @itemx QTStart    
 @itemx QTStop     
+@itemx QTEnable
+@itemx QTDisable
 @itemx QTinit     
 @itemx QTro       
 @itemx qTStatus   
@@ -34308,6 +34326,18 @@ instruction reply packet}).
 @item QTStop
 End the tracepoint experiment.  Stop collecting trace frames.
 
+@item QTEnable:@var{n}:@var{addr}
+@anchor{QTEnable}
+Enable tracepoint @var{n} at address @var{addr} in a started tracepoint
+experiment.  If the tracepoint was previously disabled, then collection
+of data from it will resume.
+
+@item QTDisable:@var{n}:@var{addr}
+@anchor{QTDisable}
+Disable tracepoint @var{n} at address @var{addr} in a started tracepoint
+experiment.  No more data will be collected from the tracepoint unless
+@samp{QTEnable:@var{n}:@var{addr}} is subsequently issued.
+
 @item QTinit
 Clear the table of tracepoints, and empty the trace frame buffer.
 
index bea804d9ab7b32c6ea00fe3641131d63d3d44c81..c5ae99fd9c3b938868d92930451b4f2a03bc06ac 100644 (file)
@@ -1,3 +1,18 @@
+2011-05-12  Kwok Cheung Yeung  <kcy@codesourcery.com>
+
+       * server.c (handle_query): Add EnableDisableTracepoints to the list
+       of supported features.
+       * tracepoint.c (clear_installed_tracepoints): Uninstall disabled
+       tracepoints.
+       (cmd_qtenable_disable): New.
+       (cmd_qtstart): Install tracepoints even if disabled.
+       (handle_tracepoint_general_set): Add call to cmd_qtenable_disable on
+       receiving a QTEnable or QTDisable packet.
+       (gdb_collect): Skip data collection if fast tracepoint is disabled.
+       (ust_marker_to_static_tracepoint): Do not ignore disabled static
+       tracepoints.
+       (gdb_probe): Skip data collection if static tracepoint is disabled.
+
 2011-05-10  Doug Evans  <dje@google.com>
 
        * thread-db.c (thread_db_handle_monitor_command): Handle elided path.
index 6bf6eaac00435ff1fa3818dc4578654c67551290..fd06c8f9a2a0ec0ea149a0996e41db39e314d5b6 100644 (file)
@@ -1540,6 +1540,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
          strcat (own_buf, ";StaticTracepoints+");
          strcat (own_buf, ";qXfer:statictrace:read+");
          strcat (own_buf, ";qXfer:traceframe-info:read+");
+         strcat (own_buf, ";EnableDisableTracepoints+");
        }
 
       return;
index 0916835115dfc3fb057a673129318bf45e72cc50..dc1050e4c7412809e3be0ad6f420fa9d5f0bd524 100644 (file)
@@ -2214,9 +2214,6 @@ clear_installed_tracepoints (void)
   /* Restore any bytes overwritten by tracepoints.  */
   for (tpoint = tracepoints; tpoint; tpoint = tpoint->next)
     {
-      if (!tpoint->enabled)
-       continue;
-
       /* Catch the case where we might try to remove a tracepoint that
         was never actually installed.  */
       if (tpoint->handle == NULL)
@@ -2454,6 +2451,73 @@ cmd_qtdv (char *own_buf)
   write_ok (own_buf);
 }
 
+static void
+cmd_qtenable_disable (char *own_buf, int enable)
+{
+  char *packet = own_buf;
+  ULONGEST num, addr;
+  struct tracepoint *tp;
+
+  packet += strlen (enable ? "QTEnable:" : "QTDisable:");
+  packet = unpack_varlen_hex (packet, &num);
+  ++packet; /* skip a colon */
+  packet = unpack_varlen_hex (packet, &addr);
+
+  tp = find_tracepoint (num, addr);
+
+  if (tp)
+    {
+      if ((enable && tp->enabled) || (!enable && !tp->enabled))
+       {
+         trace_debug ("Tracepoint %d at 0x%s is already %s",
+                      (int) num, paddress (addr),
+                      enable ? "enabled" : "disabled");
+         write_ok (own_buf);
+         return;
+       }
+
+      trace_debug ("%s tracepoint %d at 0x%s",
+                  enable ? "Enabling" : "Disabling",
+                  (int) num, paddress (addr));
+
+      tp->enabled = enable;
+
+      if (tp->type == fast_tracepoint || tp->type == static_tracepoint)
+       {
+         int ret;
+         int offset = offsetof (struct tracepoint, enabled);
+         CORE_ADDR obj_addr = tp->obj_addr_on_target + offset;
+
+         ret = prepare_to_access_memory ();
+         if (ret)
+           {
+             trace_debug ("Failed to temporarily stop inferior threads");
+             write_enn (own_buf);
+             return;
+           }
+         
+         ret = write_inferior_integer (obj_addr, enable);
+         done_accessing_memory ();
+         
+         if (ret)
+           {
+             trace_debug ("Cannot write enabled flag into "
+                          "inferior process memory");
+             write_enn (own_buf);
+             return;
+           }
+       }
+
+      write_ok (own_buf);
+    }
+  else
+    {
+      trace_debug ("Tracepoint %d at 0x%s not found",
+                  (int) num, paddress (addr));
+      write_enn (own_buf);
+    }
+}
+
 static void
 cmd_qtv (char *own_buf)
 {
@@ -2719,9 +2783,6 @@ cmd_qtstart (char *packet)
       /* Ensure all the hit counts start at zero.  */
       tpoint->hit_count = 0;
 
-      if (!tpoint->enabled)
-       continue;
-
       if (tpoint->type == trap_tracepoint)
        {
          ++slow_tracepoint_count;
@@ -3461,6 +3522,16 @@ handle_tracepoint_general_set (char *packet)
       cmd_qtdpsrc (packet);
       return 1;
     }
+  else if (strncmp ("QTEnable:", packet, strlen ("QTEnable:")) == 0)
+    {
+      cmd_qtenable_disable (packet, 1);
+      return 1;
+    }
+  else if (strncmp ("QTDisable:", packet, strlen ("QTDisable:")) == 0)
+    {
+      cmd_qtenable_disable (packet, 0);
+      return 1;
+    }
   else if (strncmp ("QTDV:", packet, strlen ("QTDV:")) == 0)
     {
       cmd_qtdv (packet);
@@ -5340,6 +5411,9 @@ gdb_collect (struct tracepoint *tpoint, unsigned char *regs)
   if (!tracing)
     return;
 
+  if (!tpoint->enabled)
+    return;
+
   ctx.base.type = fast_tracepoint;
   ctx.regs = regs;
   ctx.regcache_initted = 0;
@@ -6598,7 +6672,7 @@ ust_marker_to_static_tracepoint (const struct marker *mdata)
 
   for (tpoint = tracepoints; tpoint; tpoint = tpoint->next)
     {
-      if (!tpoint->enabled || tpoint->type != static_tracepoint)
+      if (tpoint->type != static_tracepoint)
        continue;
 
       if (tpoint->address == (uintptr_t) mdata->location)
@@ -6653,6 +6727,12 @@ gdb_probe (const struct marker *mdata, void *probe_private,
       return;
     }
 
+  if (!tpoint->enabled)
+    {
+      trace_debug ("gdb_probe: tracepoint disabled");
+      return;
+    }
+
   ctx.tpoint = tpoint;
 
   trace_debug ("gdb_probe: collecting marker: "
index 76c137a2d1db452a897847e2f4caba7c0e958e79..ff64b042241815ffab3ced183ab09eca869f247b 100644 (file)
@@ -329,6 +329,10 @@ struct remote_state
      disconnected.  */
   int disconnected_tracing;
 
+  /* True if the stub reports support for enabling and disabling
+     tracepoints while a trace experiment is running.  */
+  int enable_disable_tracepoints;
+
   /* Nonzero if the user has pressed Ctrl-C, but the target hasn't
      responded to that.  */
   int ctrlc_pending_p;
@@ -3689,6 +3693,16 @@ remote_disconnected_tracing_feature (const struct protocol_feature *feature,
   rs->disconnected_tracing = (support == PACKET_ENABLE);
 }
 
+static void
+remote_enable_disable_tracepoint_feature (const struct protocol_feature *feature,
+                                         enum packet_support support,
+                                         const char *value)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  rs->enable_disable_tracepoints = (support == PACKET_ENABLE);
+}
+
 static struct protocol_feature remote_protocol_features[] = {
   { "PacketSize", PACKET_DISABLE, remote_packet_size, -1 },
   { "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet,
@@ -3735,6 +3749,8 @@ static struct protocol_feature remote_protocol_features[] = {
     PACKET_TracepointSource },
   { "QAllow", PACKET_DISABLE, remote_supported_packet,
     PACKET_QAllow },
+  { "EnableDisableTracepoints", PACKET_DISABLE,
+    remote_enable_disable_tracepoint_feature, -1 },
 };
 
 static char *remote_support_xml;
@@ -9648,6 +9664,14 @@ remote_supports_static_tracepoints (void)
   return rs->static_tracepoints;
 }
 
+static int
+remote_supports_enable_disable_tracepoint (void)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  return rs->enable_disable_tracepoints;
+}
+
 static void
 remote_trace_init (void)
 {
@@ -9918,6 +9942,38 @@ remote_download_trace_state_variable (struct trace_state_variable *tsv)
     error (_("Error on target while downloading trace state variable."));
 }
 
+static void
+remote_enable_tracepoint (struct bp_location *location)
+{
+  struct remote_state *rs = get_remote_state ();
+  char addr_buf[40];
+
+  sprintf_vma (addr_buf, location->address);
+  sprintf (rs->buf, "QTEnable:%x:%s", location->owner->number, addr_buf);
+  putpkt (rs->buf);
+  remote_get_noisy_reply (&rs->buf, &rs->buf_size);
+  if (*rs->buf == '\0')
+    error (_("Target does not support enabling tracepoints while a trace run is ongoing."));
+  if (strcmp (rs->buf, "OK") != 0)
+    error (_("Error on target while enabling tracepoint."));
+}
+
+static void
+remote_disable_tracepoint (struct bp_location *location)
+{
+  struct remote_state *rs = get_remote_state ();
+  char addr_buf[40];
+
+  sprintf_vma (addr_buf, location->address);
+  sprintf (rs->buf, "QTDisable:%x:%s", location->owner->number, addr_buf);
+  putpkt (rs->buf);
+  remote_get_noisy_reply (&rs->buf, &rs->buf_size);
+  if (*rs->buf == '\0')
+    error (_("Target does not support disabling tracepoints while a trace run is ongoing."));
+  if (strcmp (rs->buf, "OK") != 0)
+    error (_("Error on target while disabling tracepoint."));
+}
+
 static void
 remote_trace_set_readonly_regions (void)
 {
@@ -10308,10 +10364,13 @@ Specify the serial device it is connected to\n\
   remote_ops.to_terminal_ours = remote_terminal_ours;
   remote_ops.to_supports_non_stop = remote_supports_non_stop;
   remote_ops.to_supports_multi_process = remote_supports_multi_process;
+  remote_ops.to_supports_enable_disable_tracepoint = remote_supports_enable_disable_tracepoint;
   remote_ops.to_trace_init = remote_trace_init;
   remote_ops.to_download_tracepoint = remote_download_tracepoint;
   remote_ops.to_download_trace_state_variable
     = remote_download_trace_state_variable;
+  remote_ops.to_enable_tracepoint = remote_enable_tracepoint;
+  remote_ops.to_disable_tracepoint = remote_disable_tracepoint;
   remote_ops.to_trace_set_readonly_regions = remote_trace_set_readonly_regions;
   remote_ops.to_trace_start = remote_trace_start;
   remote_ops.to_get_trace_status = remote_get_trace_status;
index 9c522cb39a309c43598a71c3f17dd103099b2c8a..ed2da34744cc534c74afede90930ca9a0dfb7986 100644 (file)
@@ -659,9 +659,12 @@ update_current_target (void)
       INHERIT (to_get_ada_task_ptid, t);
       /* Do not inherit to_search_memory.  */
       INHERIT (to_supports_multi_process, t);
+      INHERIT (to_supports_enable_disable_tracepoint, t);
       INHERIT (to_trace_init, t);
       INHERIT (to_download_tracepoint, t);
       INHERIT (to_download_trace_state_variable, t);
+      INHERIT (to_enable_tracepoint, t);
+      INHERIT (to_disable_tracepoint, t);
       INHERIT (to_trace_set_readonly_regions, t);
       INHERIT (to_trace_start, t);
       INHERIT (to_get_trace_status, t);
@@ -825,6 +828,9 @@ update_current_target (void)
   de_fault (to_supports_multi_process,
            (int (*) (void))
            return_zero);
+  de_fault (to_supports_enable_disable_tracepoint,
+           (int (*) (void))
+           return_zero);
   de_fault (to_trace_init,
            (void (*) (void))
            tcomplain);
@@ -834,6 +840,12 @@ update_current_target (void)
   de_fault (to_download_trace_state_variable,
            (void (*) (struct trace_state_variable *))
            tcomplain);
+  de_fault (to_enable_tracepoint,
+           (void (*) (struct bp_location *))
+           tcomplain);
+  de_fault (to_disable_tracepoint,
+           (void (*) (struct bp_location *))
+           tcomplain);
   de_fault (to_trace_set_readonly_regions,
            (void (*) (void))
            tcomplain);
index 52e02761a033caf392c34b9577b2d23ee137c4b4..fd58bd95c98d9d5e1138b45caabfb744b64d0eff 100644 (file)
@@ -28,6 +28,7 @@ struct objfile;
 struct ui_file;
 struct mem_attrib;
 struct target_ops;
+struct bp_location;
 struct bp_target_info;
 struct regcache;
 struct target_section_table;
@@ -644,6 +645,10 @@ struct target_ops
        simultaneously?  */
     int (*to_supports_multi_process) (void);
 
+    /* Does this target support enabling and disabling tracepoints while a trace
+       experiment is running?  */
+    int (*to_supports_enable_disable_tracepoint) (void);
+
     /* Determine current architecture of thread PTID.
 
        The target is supposed to determine the architecture of the code where
@@ -674,6 +679,12 @@ struct target_ops
     /* Send full details of a trace state variable to the target.  */
     void (*to_download_trace_state_variable) (struct trace_state_variable *tsv);
 
+    /* Enable a tracepoint on the target.  */
+    void (*to_enable_tracepoint) (struct bp_location *location);
+
+    /* Disable a tracepoint on the target.  */
+    void (*to_disable_tracepoint) (struct bp_location *location);
+
     /* Inform the target info of memory regions that are readonly
        (such as text sections), and so it should return data from
        those rather than look in the trace buffer.  */
@@ -873,6 +884,12 @@ struct address_space *target_thread_address_space (ptid_t);
 #define        target_supports_multi_process() \
      (*current_target.to_supports_multi_process) ()
 
+/* Returns true if this target can enable and disable tracepoints
+   while a trace experiment is running.  */
+
+#define target_supports_enable_disable_tracepoint() \
+  (*current_target.to_supports_enable_disable_tracepoint) ()
+
 /* Invalidate all target dcaches.  */
 extern void target_dcache_invalidate (void);
 
@@ -1457,6 +1474,12 @@ extern int target_search_memory (CORE_ADDR start_addr,
 #define target_download_trace_state_variable(tsv) \
   (*current_target.to_download_trace_state_variable) (tsv)
 
+#define target_enable_tracepoint(loc) \
+  (*current_target.to_enable_tracepoint) (loc)
+
+#define target_disable_tracepoint(loc) \
+  (*current_target.to_disable_tracepoint) (loc)
+
 #define target_trace_start() \
   (*current_target.to_trace_start) ()
 
index 119ab221d50c6ec796b01fa7e596f2dcc4e1a235..ab390152e8a84394b7db221c860021504085f490 100644 (file)
@@ -1583,11 +1583,17 @@ start_tracing (void)
                 (t->type == bp_fast_tracepoint ? "fast " : ""), t->number);
     }
 
-  /* No point in tracing with only disabled tracepoints.  */
   if (!any_enabled)
     {
-      VEC_free (breakpoint_p, tp_vec);
-      error (_("No tracepoints enabled, not starting trace"));
+      if (target_supports_enable_disable_tracepoint ())
+       warning (_("No tracepoints enabled"));
+      else
+       {
+         /* No point in tracing with only disabled tracepoints that
+            cannot be re-enabled.  */
+         VEC_free (breakpoint_p, tp_vec);
+         error (_("No tracepoints enabled, not starting trace"));
+       }
     }
 
   if (num_to_download <= 0)
This page took 0.103575 seconds and 4 git commands to generate.