Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Stan Shebs <stan_shebs@mentor.com>
To: gdb-patches@sourceware.org
Subject: [PATCH] Tracing notes and metadata
Date: Mon, 17 Oct 2011 16:27:00 -0000	[thread overview]
Message-ID: <4E9C5112.9070705@mentor.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 3768 bytes --]

This patch brings social networking to GDB! :-) OK, it's a little more 
mundane; a consequence of disconnecting tracing is that the tracing run 
can be out on its own for a long time, and in a lab situation with 
multiple users, it is useful to be able to tell other people something 
about the trace run in progress, so they can know whether to leave it 
alone, try to contact you, or shut it down with a note explaining why 
you needed to stop it.

With this patch, any arguments to tstart and tstop are recorded with the 
trace run as free-form text, and reported as part of its status.  Also, 
there is a trace-user variable (which is free form text which is 
typically constant and you can set in your .gdbinit), and set/show 
variables for the start and stop notes as well.

In addition, this patch adds start/stop timestamps and per-tracepoint 
hit counts and traceframe usage.

The patch still needs testsuite and NEWS, but considering the user 
interface tinkering, it seemed like a good idea to solicit feedback 
before committing to all the details.

Stan
stan@codesourcery.com

2011-10-17  Stan Shebs <stan@codesourcery.com>

     * breakpoint.h (struct tracepoint): New field traceframe_usage.
     * breakpoint.c (print_one_breakpoint_location): Identify
     tracepoints as such when reporting hit counts, report
     trace buffer usage.
     (create_tracepoint_from_upload): Copy status info.
     * tracepoint.h (struct trace_status): Rename error_desc to stop_desc,
     add fields user_name, notes, start_time, stop_time.
     (struct uploaded_tp): Add fields hit_count, traceframe_usage.
     * tracepoint.c (trace_user): New global.
     (trace_notes): New global.
     (trace_stop_notes): New global.
     (start_tracing): Add argument and trace note handling.
     (stop_tracing): Ditto.
     (trace_start_command): Add notes argument.
     (trace_stop_command): Ditto.
     (trace_status_command): Report additional status info.
     (trace_status_mi): Update.
     (trace_save): Update, record tracepoint status.
     (set_disconnected_tracing): Call target method directly.
     (send_disconnected_tracing_value): Remove.
     (set_trace_user): New function.
     (set_trace_notes): New function.
     (set_trace_stop_notes): New function.
     (parse_trace_status): Handle additional status.
     (parse_tracepoint_status): New function.
     (parse_tracepoint_definition): Call it.
     (tfile_get_tracepoint_status): New function.
     (init_tfile_ops): Use it.
     (_initialize_tracepoint): Add new setshows.
     * target.h (struct target_ops): New methods to_get_tracepoint_status
     and to_set_trace_notes.
     (target_get_tracepoint_status): New macro.
     (target_set_trace_notes): New macro.
     * target.c (update_current_target): Add new methods.
     * remote.c (remote_get_tracepoint_status): New function.
     (remote_set_trace_notes): New function.
     (init_remote_ops): Add them.
     * mi/mi-main.c (mi_cmd_trace_start): Add argument to call.
     (mi_cmd_trace_stop): Ditto.

     [gdbserver]
     * tracepoint.c (struct tracepoint): New field traceframe_usage.
     (start_time): New global.
     (stop_time): New global.
     (tracing_user_name): New global.
     (tracing_notes): New global.
     (cmd_qtstart): Set traceframe_usage, start_time.
     (stop_tracing): Set stop_time.
     (cmd_qtstatus): Report additional status.
     (cmd_qtp): New function.
     (handle_tracepoint_query): Call it.
     (cmd_qtnotes): New function.
     (handle_tracepoint_general_set): Call it.
     (get_timestamp): Rename from tsv_get_timestamp.

     [doc]
     * gdb.texinfo (Starting and Stopping Trace Experiments): Document
     note-related options and variables.
     (Tracepoint Packets): Document packet changes.


[-- Attachment #2: tmeta-patch-1 --]
[-- Type: text/plain, Size: 46375 bytes --]

? tmeta-patch-1
Index: breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.616
diff -p -r1.616 breakpoint.c
*** breakpoint.c	12 Oct 2011 15:43:48 -0000	1.616
--- breakpoint.c	17 Oct 2011 15:13:46 -0000
*************** print_one_breakpoint_location (struct br
*** 4889,4894 ****
--- 4889,4896 ----
        /* FIXME should make an annotation for this.  */
        if (ep_is_catchpoint (b))
  	ui_out_text (uiout, "\tcatchpoint");
+       else if (is_tracepoint (b))
+ 	ui_out_text (uiout, "\ttracepoint");
        else
  	ui_out_text (uiout, "\tbreakpoint");
        ui_out_text (uiout, " already hit ");
*************** print_one_breakpoint_location (struct br
*** 4913,4918 ****
--- 4915,4932 ----
        ui_out_text (uiout, " hits\n");
      }
  
+   if (!part_of_multiple && is_tracepoint (b))
+     {
+       struct tracepoint *tp = (struct tracepoint *) b;
+ 
+       if (tp->traceframe_usage)
+ 	{
+ 	  ui_out_text (uiout, "\ttrace buffer usage ");
+ 	  ui_out_field_int (uiout, "traceframe-usage", tp->traceframe_usage);
+ 	  ui_out_text (uiout, " bytes\n");
+ 	}
+     }
+   
    l = b->commands ? b->commands->commands : NULL;
    if (!part_of_multiple && l)
      {
*************** create_tracepoint_from_upload (struct up
*** 12848,12853 ****
--- 12862,12871 ----
  	       "have no source form, ignoring them"),
  	     utp->number);
  
+   /* Copy any status information that might be available.  */
+   tp->base.hit_count = utp->hit_count;
+   tp->traceframe_usage = utp->traceframe_usage;
+ 
    return tp;
  }
    
Index: breakpoint.h
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.h,v
retrieving revision 1.161
diff -p -r1.161 breakpoint.h
*** breakpoint.h	12 Oct 2011 15:43:49 -0000	1.161
--- breakpoint.h	17 Oct 2011 15:13:46 -0000
*************** struct tracepoint
*** 706,711 ****
--- 706,715 ----
    /* The number of the tracepoint on the target.  */
    int number_on_target;
  
+   /* The total space taken by all the trace frames for this
+      tracepoint.  */
+   ULONGEST traceframe_usage;
+ 
    /* The static tracepoint marker id, if known.  */
    char *static_trace_marker_id;
  
Index: remote.c
===================================================================
RCS file: /cvs/src/src/gdb/remote.c,v
retrieving revision 1.465
diff -p -r1.465 remote.c
*** remote.c	13 Oct 2011 13:15:16 -0000	1.465
--- remote.c	17 Oct 2011 15:13:46 -0000
*************** remote_get_trace_status (struct trace_st
*** 10145,10150 ****
--- 10145,10197 ----
    return ts->running;
  }
  
+ void
+ remote_get_tracepoint_status (struct breakpoint *bp,
+ 			      struct uploaded_tp *utp)
+ {
+   struct remote_state *rs = get_remote_state ();
+   char addrbuf[40];
+   char *reply;
+   struct bp_location *loc;
+   struct tracepoint *tp = (struct tracepoint *) bp;
+ 
+   if (tp)
+     {
+       tp->base.hit_count = 0;
+       tp->traceframe_usage = 0;
+       for (loc = tp->base.loc; loc; loc = loc->next)
+ 	{
+ 	  /* If the tracepoint was never downloaded, don't go asking for
+ 	     any status.  */
+ 	  if (tp->number_on_target == 0)
+ 	    continue;
+ 	  sprintf_vma (addrbuf, loc->address);
+ 	  sprintf (rs->buf, "qTP:%x:%s", tp->number_on_target, addrbuf);
+ 	  putpkt (rs->buf);
+ 	  reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
+ 	  if (reply && *reply)
+ 	    {
+ 	      if (*reply == 'V')
+ 		parse_tracepoint_status (reply + 1, bp, utp);
+ 	    }
+ 	}
+     }
+   else if (utp)
+     {
+       utp->hit_count = 0;
+       utp->traceframe_usage = 0;
+       sprintf_vma (addrbuf, (long unsigned int) utp->addr);
+       sprintf (rs->buf, "qTP:%x:%s", utp->number, addrbuf);
+       putpkt (rs->buf);
+       reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
+       if (reply && *reply)
+ 	{
+ 	  if (*reply == 'V')
+ 	    parse_tracepoint_status (reply + 1, bp, utp);
+ 	}
+     }
+ }
+ 
  static void
  remote_trace_stop (void)
  {
*************** remote_traceframe_info (void)
*** 10390,10395 ****
--- 10437,10485 ----
    return NULL;
  }
  
+ static int
+ remote_set_trace_notes (char *user, char *notes, char *stop_notes)
+ {
+   struct remote_state *rs = get_remote_state ();
+   char *reply;
+   char *buf = rs->buf;
+   char *endbuf = rs->buf + get_remote_packet_size ();
+   int nbytes;
+ 
+   buf += xsnprintf (buf, endbuf - buf, "QTNotes:");
+   if (user)
+     {
+       buf += xsnprintf (buf, endbuf - buf, "user:");
+       nbytes = bin2hex (user, buf, 0);
+       buf += 2 * nbytes;
+       *buf++ = ';';
+     }
+   if (notes)
+     {
+       buf += xsnprintf (buf, endbuf - buf, "notes:");
+       nbytes = bin2hex (notes, buf, 0);
+       buf += 2 * nbytes;
+       *buf++ = ';';
+     }
+   if (stop_notes)
+     {
+       buf += xsnprintf (buf, endbuf - buf, "tstop:");
+       nbytes = bin2hex (stop_notes, buf, 0);
+       buf += 2 * nbytes;
+       *buf++ = ';';
+     }
+ 
+   putpkt (rs->buf);
+   reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
+   if (*reply == '\0')
+     return 0;
+ 
+   if (strcmp (reply, "OK") != 0)
+     error (_("Bogus reply from target: %s"), reply);
+ 
+   return 1;
+ }
+ 
  static void
  init_remote_ops (void)
  {
*************** Specify the serial device it is connecte
*** 10468,10473 ****
--- 10558,10564 ----
    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;
+   remote_ops.to_get_tracepoint_status = remote_get_tracepoint_status;
    remote_ops.to_trace_stop = remote_trace_stop;
    remote_ops.to_trace_find = remote_trace_find;
    remote_ops.to_get_trace_state_variable_value
*************** Specify the serial device it is connecte
*** 10479,10484 ****
--- 10570,10576 ----
    remote_ops.to_get_raw_trace_data = remote_get_raw_trace_data;
    remote_ops.to_set_disconnected_tracing = remote_set_disconnected_tracing;
    remote_ops.to_set_circular_trace_buffer = remote_set_circular_trace_buffer;
+   remote_ops.to_set_trace_notes = remote_set_trace_notes;
    remote_ops.to_core_of_thread = remote_core_of_thread;
    remote_ops.to_verify_memory = remote_verify_memory;
    remote_ops.to_get_tib_address = remote_get_tib_address;
Index: target.c
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.286
diff -p -r1.286 target.c
*** target.c	7 Oct 2011 12:06:46 -0000	1.286
--- target.c	17 Oct 2011 15:13:46 -0000
*************** update_current_target (void)
*** 680,685 ****
--- 680,686 ----
        INHERIT (to_trace_set_readonly_regions, t);
        INHERIT (to_trace_start, t);
        INHERIT (to_get_trace_status, t);
+       INHERIT (to_get_tracepoint_status, t);
        INHERIT (to_trace_stop, t);
        INHERIT (to_trace_find, t);
        INHERIT (to_get_trace_state_variable_value, t);
*************** update_current_target (void)
*** 689,694 ****
--- 690,696 ----
        INHERIT (to_get_raw_trace_data, t);
        INHERIT (to_set_disconnected_tracing, t);
        INHERIT (to_set_circular_trace_buffer, t);
+       INHERIT (to_set_trace_notes, t);
        INHERIT (to_get_tib_address, t);
        INHERIT (to_set_permissions, t);
        INHERIT (to_static_tracepoint_marker_at, t);
*************** update_current_target (void)
*** 864,869 ****
--- 866,874 ----
    de_fault (to_get_trace_status,
  	    (int (*) (struct trace_status *))
  	    return_minus_one);
+   de_fault (to_get_tracepoint_status,
+ 	    (void (*) (struct breakpoint *, struct uploaded_tp *))
+ 	    tcomplain);
    de_fault (to_trace_stop,
  	    (void (*) (void))
  	    tcomplain);
*************** update_current_target (void)
*** 891,896 ****
--- 896,904 ----
    de_fault (to_set_circular_trace_buffer,
  	    (void (*) (int))
  	    target_ignore);
+   de_fault (to_set_trace_notes,
+ 	    (int (*) (char *, char *, char *))
+ 	    return_zero);
    de_fault (to_get_tib_address,
  	    (int (*) (ptid_t, CORE_ADDR *))
  	    tcomplain);
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.213
diff -p -r1.213 target.h
*** target.h	7 Oct 2011 12:06:46 -0000	1.213
--- target.h	17 Oct 2011 15:13:46 -0000
*************** struct target_ops
*** 703,708 ****
--- 703,711 ----
      /* Get the current status of a tracing run.  */
      int (*to_get_trace_status) (struct trace_status *ts);
  
+     void (*to_get_tracepoint_status) (struct breakpoint *tp,
+ 				      struct uploaded_tp *utp);
+ 
      /* Stop a trace run.  */
      void (*to_trace_stop) (void);
  
*************** struct target_ops
*** 733,738 ****
--- 736,745 ----
      void (*to_set_disconnected_tracing) (int val);
      void (*to_set_circular_trace_buffer) (int val);
  
+     /* Add/change textual notes about the trace run, returning 1 if
+        successful, 0 otherwise.  */
+     int (*to_set_trace_notes) (char *user, char *notes, char* stopnotes);
+ 
      /* Return the processor core that thread PTID was last seen on.
         This information is updated only when:
         - update_thread_list is called
*************** extern int target_search_memory (CORE_AD
*** 1486,1491 ****
--- 1493,1501 ----
  #define target_get_trace_status(ts) \
    (*current_target.to_get_trace_status) (ts)
  
+ #define target_get_tracepoint_status(tp,utp)		\
+   (*current_target.to_get_tracepoint_status) (tp, utp)
+ 
  #define target_trace_stop() \
    (*current_target.to_trace_stop) ()
  
*************** extern int target_search_memory (CORE_AD
*** 1513,1518 ****
--- 1523,1531 ----
  #define	target_set_circular_trace_buffer(val)	\
    (*current_target.to_set_circular_trace_buffer) (val)
  
+ #define	target_set_trace_notes(user,notes,stopnotes)		\
+   (*current_target.to_set_trace_notes) ((user), (notes), (stopnotes))
+ 
  #define target_get_tib_address(ptid, addr) \
    (*current_target.to_get_tib_address) ((ptid), (addr))
  
Index: tracepoint.c
===================================================================
RCS file: /cvs/src/src/gdb/tracepoint.c,v
retrieving revision 1.233
diff -p -r1.233 tracepoint.c
*** tracepoint.c	13 Oct 2011 13:06:18 -0000	1.233
--- tracepoint.c	17 Oct 2011 15:13:46 -0000
*************** static int disconnected_tracing;
*** 177,182 ****
--- 177,194 ----
  
  static int circular_trace_buffer;
  
+ /* Textual notes applying to the current and/or future trace runs.  */
+ 
+ char *trace_user = NULL;
+ 
+ /* Textual notes applying to the current and/or future trace runs.  */
+ 
+ char *trace_notes = NULL;
+ 
+ /* Textual notes applying to the stopping of a trace.  */
+ 
+ char *trace_stop_notes = NULL;
+ 
  /* ======= Important command functions: ======= */
  static void trace_actions_command (char *, int);
  static void trace_start_command (char *, int);
*************** static char *mem2hex (gdb_byte *, char *
*** 198,205 ****
  static void add_register (struct collection_list *collection,
  			  unsigned int regno);
  
- extern void send_disconnected_tracing_value (int value);
- 
  static void free_uploaded_tps (struct uploaded_tp **utpp);
  static void free_uploaded_tsvs (struct uploaded_tsv **utsvp);
  
--- 210,215 ----
*************** add_aexpr (struct collection_list *colle
*** 1595,1608 ****
  
  
  void
! start_tracing (void)
  {
    VEC(breakpoint_p) *tp_vec = NULL;
    int ix;
    struct breakpoint *b;
    struct trace_state_variable *tsv;
    int any_enabled = 0, num_to_download = 0;
!   
    tp_vec = all_tracepoints ();
  
    /* No point in tracing without any tracepoints...  */
--- 1605,1619 ----
  
  
  void
! start_tracing (char *notes)
  {
    VEC(breakpoint_p) *tp_vec = NULL;
    int ix;
    struct breakpoint *b;
    struct trace_state_variable *tsv;
    int any_enabled = 0, num_to_download = 0;
!   int ret;
! 
    tp_vec = all_tracepoints ();
  
    /* No point in tracing without any tracepoints...  */
*************** start_tracing (void)
*** 1676,1681 ****
--- 1687,1699 ----
    target_set_disconnected_tracing (disconnected_tracing);
    target_set_circular_trace_buffer (circular_trace_buffer);
  
+   if (!notes)
+     notes = trace_notes;
+   ret = target_set_trace_notes (trace_user, notes, NULL);
+ 
+   if (!ret && (trace_user || notes))
+     warning ("Target does not support trace user/notes, info ignored");
+ 
    /* Now insert traps and begin collecting data.  */
    target_trace_start ();
  
*************** start_tracing (void)
*** 1687,1698 ****
    clear_traceframe_info ();
  }
  
! /* tstart command:
! 
!    Tell target to clear any previous trace experiment.
!    Walk the list of tracepoints, and send them (and their actions)
!    to the target.  If no errors,
!    Tell target to start a new trace experiment.  */
  
  static void
  trace_start_command (char *args, int from_tty)
--- 1705,1715 ----
    clear_traceframe_info ();
  }
  
! /* The tstart command requests the target to start a new trace run.
!    The command passes any arguments it has to the target verbatim, as
!    an optional "trace note".  This is useful as for instance a warning
!    to other users if the trace runs disconnected, and you don't want
!    anybody else messing with the target.  */
  
  static void
  trace_start_command (char *args, int from_tty)
*************** trace_start_command (char *args, int fro
*** 1706,1728 ****
  	error (_("New trace run not started."));
      }
  
!   start_tracing ();
  }
  
! /* tstop command */
  static void
  trace_stop_command (char *args, int from_tty)
  {
    if (!current_trace_status ()->running)
      error (_("Trace is not running."));
  
!   stop_tracing ();
  }
  
  void
! stop_tracing (void)
  {
    target_trace_stop ();
    /* Should change in response to reply?  */
    current_trace_status ()->running = 0;
  }
--- 1723,1759 ----
  	error (_("New trace run not started."));
      }
  
!   start_tracing (args);
  }
  
! /* The tstop command stops the tracing run.  The command passes any
!    supplied arguments to the target verbatim as a "stop note"; if the
!    target supports trace notes, then it will be reported back as part
!    of the trace run's status.  */
! 
  static void
  trace_stop_command (char *args, int from_tty)
  {
    if (!current_trace_status ()->running)
      error (_("Trace is not running."));
  
!   stop_tracing (args);
  }
  
  void
! stop_tracing (char *note)
  {
+   int ret;
+ 
    target_trace_stop ();
+ 
+   if (!note)
+     note = trace_stop_notes;
+   ret = target_set_trace_notes (NULL, NULL, note);
+ 
+   if (!ret && note)
+     warning ("Target does not support trace notes, note ignored");
+ 
    /* Should change in response to reply?  */
    current_trace_status ()->running = 0;
  }
*************** static void
*** 1732,1738 ****
  trace_status_command (char *args, int from_tty)
  {
    struct trace_status *ts = current_trace_status ();
!   int status;
    
    status = target_get_trace_status (ts);
  
--- 1763,1771 ----
  trace_status_command (char *args, int from_tty)
  {
    struct trace_status *ts = current_trace_status ();
!   int status, ix;
!   VEC(breakpoint_p) *tp_vec = NULL;
!   struct breakpoint *t;
    
    status = target_get_trace_status (ts);
  
*************** trace_status_command (char *args, int fr
*** 1763,1769 ****
  	  printf_filtered (_("No trace has been run on the target.\n"));
  	  break;
  	case tstop_command:
! 	  printf_filtered (_("Trace stopped by a tstop command.\n"));
  	  break;
  	case trace_buffer_full:
  	  printf_filtered (_("Trace stopped because the buffer was full.\n"));
--- 1796,1806 ----
  	  printf_filtered (_("No trace has been run on the target.\n"));
  	  break;
  	case tstop_command:
! 	  if (ts->stop_desc)
! 	    printf_filtered (_("Trace stopped by a tstop command (%s).\n"),
! 			     ts->stop_desc);
! 	  else
! 	    printf_filtered (_("Trace stopped by a tstop command.\n"));
  	  break;
  	case trace_buffer_full:
  	  printf_filtered (_("Trace stopped because the buffer was full.\n"));
*************** trace_status_command (char *args, int fr
*** 1779,1788 ****
  	  if (ts->stopping_tracepoint)
  	    printf_filtered (_("Trace stopped by an "
  			       "error (%s, tracepoint %d).\n"),
! 			     ts->error_desc, ts->stopping_tracepoint);
  	  else
  	    printf_filtered (_("Trace stopped by an error (%s).\n"),
! 			     ts->error_desc);
  	  break;
  	case trace_stop_reason_unknown:
  	  printf_filtered (_("Trace stopped for an unknown reason.\n"));
--- 1816,1825 ----
  	  if (ts->stopping_tracepoint)
  	    printf_filtered (_("Trace stopped by an "
  			       "error (%s, tracepoint %d).\n"),
! 			     ts->stop_desc, ts->stopping_tracepoint);
  	  else
  	    printf_filtered (_("Trace stopped by an error (%s).\n"),
! 			     ts->stop_desc);
  	  break;
  	case trace_stop_reason_unknown:
  	  printf_filtered (_("Trace stopped for an unknown reason.\n"));
*************** trace_status_command (char *args, int fr
*** 1833,1844 ****
--- 1870,1895 ----
    if (ts->circular_buffer)
      printf_filtered (_("Trace buffer is circular.\n"));
  
+   if (ts->user_name && strlen (ts->user_name) > 0)
+     printf_filtered (_("Trace user is %s.\n"), ts->user_name);
+ 
+   if (ts->notes && strlen (ts->notes) > 0)
+     printf_filtered (_("Trace notes: %s.\n"), ts->notes);
+ 
    /* Now report on what we're doing with tfind.  */
    if (traceframe_number >= 0)
      printf_filtered (_("Looking at trace frame %d, tracepoint %d.\n"),
  		     traceframe_number, tracepoint_number);
    else
      printf_filtered (_("Not looking at any trace frame.\n"));
+ 
+   /* Now report any per-tracepoint status available.  */
+   tp_vec = all_tracepoints ();
+ 
+   for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++)
+     target_get_tracepoint_status (t, NULL);
+ 
+   VEC_free (breakpoint_p, tp_vec);
  }
  
  /* Report the trace status to uiout, in a way suitable for MI, and not
*************** trace_status_mi (int on_stop)
*** 1921,1927 ****
  				  stopping_tracepoint);
  	      if (ts->stop_reason == tracepoint_error)
  		ui_out_field_string (uiout, "error-description",
! 				     ts->error_desc);
  	    }
  	}
      }
--- 1972,1978 ----
  				  stopping_tracepoint);
  	      if (ts->stop_reason == tracepoint_error)
  		ui_out_field_string (uiout, "error-description",
! 				     ts->stop_desc);
  	    }
  	}
      }
*************** trace_save (const char *filename, int ta
*** 2773,2781 ****
  	   (ts->running ? '1' : '0'), stop_reason_names[ts->stop_reason]);
    if (ts->stop_reason == tracepoint_error)
      {
!       char *buf = (char *) alloca (strlen (ts->error_desc) * 2 + 1);
  
!       bin2hex ((gdb_byte *) ts->error_desc, buf, 0);
        fprintf (fp, ":%s", buf);
      }
    fprintf (fp, ":%x", ts->stopping_tracepoint);
--- 2824,2832 ----
  	   (ts->running ? '1' : '0'), stop_reason_names[ts->stop_reason]);
    if (ts->stop_reason == tracepoint_error)
      {
!       char *buf = (char *) alloca (strlen (ts->stop_desc) * 2 + 1);
  
!       bin2hex ((gdb_byte *) ts->stop_desc, buf, 0);
        fprintf (fp, ":%s", buf);
      }
    fprintf (fp, ":%x", ts->stopping_tracepoint);
*************** trace_save (const char *filename, int ta
*** 2828,2833 ****
--- 2879,2887 ----
    target_upload_tracepoints (&uploaded_tps);
  
    for (utp = uploaded_tps; utp; utp = utp->next)
+     target_get_tracepoint_status (NULL, utp);
+ 
+   for (utp = uploaded_tps; utp; utp = utp->next)
      {
        fprintf (fp, "tp T%x:%s:%c:%x:%x",
  	       utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
*************** trace_save (const char *filename, int ta
*** 2863,2868 ****
--- 2917,2927 ----
  				buf, MAX_TRACE_UPLOAD);
  	  fprintf (fp, "tp Z%s\n", buf);
  	}
+       fprintf (fp, "tp V%x:%s:%x:%s\n",
+ 	       utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
+ 	       utp->hit_count,
+ 	       phex_nz (utp->traceframe_usage,
+ 			sizeof (utp->traceframe_usage)));
      }
  
    free_uploaded_tps (&uploaded_tps);
*************** trace_save_command (char *args, int from
*** 2933,2949 ****
  /* Tell the target what to do with an ongoing tracing run if GDB
     disconnects for some reason.  */
  
- void
- send_disconnected_tracing_value (int value)
- {
-   target_set_disconnected_tracing (value);
- }
- 
  static void
  set_disconnected_tracing (char *args, int from_tty,
  			  struct cmd_list_element *c)
  {
!   send_disconnected_tracing_value (disconnected_tracing);
  }
  
  static void
--- 2992,3002 ----
  /* Tell the target what to do with an ongoing tracing run if GDB
     disconnects for some reason.  */
  
  static void
  set_disconnected_tracing (char *args, int from_tty,
  			  struct cmd_list_element *c)
  {
!   target_set_disconnected_tracing (disconnected_tracing);
  }
  
  static void
*************** set_circular_trace_buffer (char *args, i
*** 2953,2958 ****
--- 3006,3047 ----
    target_set_circular_trace_buffer (circular_trace_buffer);
  }
  
+ static void
+ set_trace_user (char *args, int from_tty,
+ 		struct cmd_list_element *c)
+ {
+   int ret;
+ 
+   ret = target_set_trace_notes (trace_user, NULL, NULL);
+ 
+   if (!ret)
+     warning ("Target does not support trace notes, user ignored");
+ }
+ 
+ static void
+ set_trace_notes (char *args, int from_tty,
+ 		 struct cmd_list_element *c)
+ {
+   int ret;
+ 
+   ret = target_set_trace_notes (NULL, trace_notes, NULL);
+ 
+   if (!ret)
+     warning ("Target does not support trace notes, note ignored");
+ }
+ 
+ static void
+ set_trace_stop_notes (char *args, int from_tty,
+ 		      struct cmd_list_element *c)
+ {
+   int ret;
+ 
+   ret = target_set_trace_notes (NULL, NULL, trace_stop_notes);
+ 
+   if (!ret)
+     warning ("Target does not support trace notes, stop note ignored");
+ }
+ 
  /* Convert the memory pointed to by mem into hex, placing result in buf.
   * Return a pointer to the last char put in buf (null)
   * "stolen" from sparc-stub.c
*************** tfile_interp_line (char *line,
*** 3523,3542 ****
  void
  parse_trace_status (char *line, struct trace_status *ts)
  {
!   char *p = line, *p1, *p2, *p_temp;
    ULONGEST val;
  
    ts->running_known = 1;
    ts->running = (*p++ == '1');
    ts->stop_reason = trace_stop_reason_unknown;
!   xfree (ts->error_desc);
!   ts->error_desc = NULL;
    ts->traceframe_count = -1;
    ts->traceframes_created = -1;
    ts->buffer_free = -1;
    ts->buffer_size = -1;
    ts->disconnected_tracing = 0;
    ts->circular_buffer = 0;
  
    while (*p++)
      {
--- 3612,3636 ----
  void
  parse_trace_status (char *line, struct trace_status *ts)
  {
!   char *p = line, *p1, *p2, *p3, *p_temp;
!   int end;
    ULONGEST val;
  
    ts->running_known = 1;
    ts->running = (*p++ == '1');
    ts->stop_reason = trace_stop_reason_unknown;
!   xfree (ts->stop_desc);
!   ts->stop_desc = NULL;
    ts->traceframe_count = -1;
    ts->traceframes_created = -1;
    ts->buffer_free = -1;
    ts->buffer_size = -1;
    ts->disconnected_tracing = 0;
    ts->circular_buffer = 0;
+   xfree (ts->user_name);
+   ts->user_name = NULL;
+   xfree (ts->notes);
+   ts->notes = NULL;
  
    while (*p++)
      {
*************** parse_trace_status (char *line, struct t
*** 3544,3549 ****
--- 3638,3646 ----
        if (p1 == NULL)
  	error (_("Malformed trace status, at %s\n\
  Status line: '%s'\n"), p, line);
+       p3 = strchr (p, ';');
+       if (p3 == NULL)
+ 	p3 = p + strlen (p);
        if (strncmp (p, stop_reason_names[trace_buffer_full], p1 - p) == 0)
  	{
  	  p = unpack_varlen_hex (++p1, &val);
*************** Status line: '%s'\n"), p, line);
*** 3563,3569 ****
  	}
        else if (strncmp (p, stop_reason_names[tstop_command], p1 - p) == 0)
  	{
! 	  p = unpack_varlen_hex (++p1, &val);
  	  ts->stop_reason = tstop_command;
  	}
        else if (strncmp (p, stop_reason_names[trace_disconnected], p1 - p) == 0)
--- 3660,3681 ----
  	}
        else if (strncmp (p, stop_reason_names[tstop_command], p1 - p) == 0)
  	{
! 	  p2 = strchr (++p1, ':');
! 	  if (!p2 || p2 > p3)
! 	    {
! 	      /*older style*/
! 	      p2 = p1;
! 	    }
! 	  else if (p2 != p1)
! 	    {
! 	      ts->stop_desc = xmalloc (strlen (line));
! 	      end = hex2bin (p1, ts->stop_desc, (p2 - p1) / 2);
! 	      ts->stop_desc[end] = '\0';
! 	    }
! 	  else
! 	    ts->stop_desc = xstrdup ("");
! 
! 	  p = unpack_varlen_hex (++p2, &val);
  	  ts->stop_reason = tstop_command;
  	}
        else if (strncmp (p, stop_reason_names[trace_disconnected], p1 - p) == 0)
*************** Status line: '%s'\n"), p, line);
*** 3576,3589 ****
  	  p2 = strchr (++p1, ':');
  	  if (p2 != p1)
  	    {
! 	      int end;
! 
! 	      ts->error_desc = xmalloc ((p2 - p1) / 2 + 1);
! 	      end = hex2bin (p1, ts->error_desc, (p2 - p1) / 2);
! 	      ts->error_desc[end] = '\0';
  	    }
  	  else
! 	    ts->error_desc = xstrdup ("");
  
  	  p = unpack_varlen_hex (++p2, &val);
  	  ts->stopping_tracepoint = val;
--- 3688,3699 ----
  	  p2 = strchr (++p1, ':');
  	  if (p2 != p1)
  	    {
! 	      ts->stop_desc = xmalloc ((p2 - p1) / 2 + 1);
! 	      end = hex2bin (p1, ts->stop_desc, (p2 - p1) / 2);
! 	      ts->stop_desc[end] = '\0';
  	    }
  	  else
! 	    ts->stop_desc = xstrdup ("");
  
  	  p = unpack_varlen_hex (++p2, &val);
  	  ts->stopping_tracepoint = val;
*************** Status line: '%s'\n"), p, line);
*** 3619,3624 ****
--- 3729,3760 ----
  	  p = unpack_varlen_hex (++p1, &val);
  	  ts->circular_buffer = val;
  	}
+       else if (strncmp (p, "starttime", p1 - p) == 0)
+ 	{
+ 	  p = unpack_varlen_hex (++p1, &val);
+ 	  ts->start_time = val;
+ 	}
+       else if (strncmp (p, "stoptime", p1 - p) == 0)
+ 	{
+ 	  p = unpack_varlen_hex (++p1, &val);
+ 	  ts->stop_time = val;
+ 	}
+       else if (strncmp (p, "username", p1 - p) == 0)
+ 	{
+ 	  ++p1;
+ 	  ts->user_name = xmalloc (strlen (p) / 2);
+ 	  end = hex2bin (p1, ts->user_name, (p3 - p1)  / 2);
+ 	  ts->user_name[end] = '\0';
+ 	  p = p3;
+ 	}
+       else if (strncmp (p, "notes", p1 - p) == 0)
+ 	{
+ 	  ++p1;
+ 	  ts->notes = xmalloc (strlen (p) / 2);
+ 	  end = hex2bin (p1, ts->notes, (p3 - p1) / 2);
+ 	  ts->notes[end] = '\0';
+ 	  p = p3;
+ 	}
        else
  	{
  	  /* Silently skip unknown optional info.  */
*************** Status line: '%s'\n"), p, line);
*** 3632,3637 ****
--- 3768,3793 ----
      }
  }
  
+ void
+ parse_tracepoint_status (char *p, struct breakpoint *bp,
+ 			 struct uploaded_tp *utp)
+ {
+   ULONGEST uval;
+   struct tracepoint *tp = (struct tracepoint *) bp;
+ 
+   p = unpack_varlen_hex (p, &uval);
+   if (tp)
+     tp->base.hit_count += uval;
+   else
+     utp->hit_count += uval;
+   p = unpack_varlen_hex (p + 1, &uval);
+   if (tp)
+     tp->traceframe_usage += uval;
+   else
+     utp->traceframe_usage += uval;
+   /* Ignore any extra, allowing for future extensions.  */
+ }
+ 
  /* Given a line of text defining a part of a tracepoint, parse it into
     an "uploaded tracepoint".  */
  
*************** parse_tracepoint_definition (char *line,
*** 3733,3738 ****
--- 3889,3900 ----
        else if (strncmp (srctype, "cmd:", strlen ("cmd:")) == 0)
  	VEC_safe_push (char_ptr, utp->cmd_strings, xstrdup (buf));
      }
+   else if (piece == 'V')
+     {
+       utp = get_uploaded_tp (num, addr, utpp);
+ 
+       parse_tracepoint_status (p, NULL, utp);
+     }
    else
      {
        /* Don't error out, the target might be sending us optional
*************** tfile_get_trace_status (struct trace_sta
*** 3808,3813 ****
--- 3970,3982 ----
    return -1;
  }
  
+ static void
+ tfile_get_tracepoint_status (struct breakpoint *tp, struct uploaded_tp *utp)
+ {
+   /* Other bits of trace status were collected as part of opening the
+      trace files, so nothing to do here.  */
+ }
+ 
  /* Given the position of a traceframe in the file, figure out what
     address the frame was collected at.  This would normally be the
     value of a collected PC register, but if not available, we
*************** init_tfile_ops (void)
*** 4349,4354 ****
--- 4518,4524 ----
    tfile_ops.to_xfer_partial = tfile_xfer_partial;
    tfile_ops.to_files_info = tfile_files_info;
    tfile_ops.to_get_trace_status = tfile_get_trace_status;
+   tfile_ops.to_get_tracepoint_status = tfile_get_tracepoint_status;
    tfile_ops.to_trace_find = tfile_trace_find;
    tfile_ops.to_get_trace_state_variable_value
      = tfile_get_trace_state_variable_value;
*************** up and stopping the trace run."),
*** 4972,4977 ****
--- 5142,5168 ----
  			   &setlist,
  			   &showlist);
  
+   add_setshow_string_cmd ("trace-user", class_trace,
+ 			  &trace_user, _("\
+ Set the user name to use for future trace runs"), _("\
+ Show the user name to use for future trace runs"), NULL,
+ 			  set_trace_user, NULL,
+ 			  &setlist, &showlist);
+ 
+   add_setshow_string_cmd ("trace-notes", class_trace,
+ 			  &trace_notes, _("\
+ Set notes string to use for future trace runs"), _("\
+ Show the notes string to use for future trace runs"), NULL,
+ 			  set_trace_notes, NULL,
+ 			  &setlist, &showlist);
+ 
+   add_setshow_string_cmd ("trace-stop-notes", class_trace,
+ 			  &trace_stop_notes, _("\
+ Set notes string to use for future tstop commands"), _("\
+ Show the notes string to use for future tstop commands"), NULL,
+ 			  set_trace_stop_notes, NULL,
+ 			  &setlist, &showlist);
+ 
    init_tfile_ops ();
  
    add_target (&tfile_ops);
Index: tracepoint.h
===================================================================
RCS file: /cvs/src/src/gdb/tracepoint.h,v
retrieving revision 1.43
diff -p -r1.43 tracepoint.h
*** tracepoint.h	25 Jul 2011 11:24:44 -0000	1.43
--- tracepoint.h	17 Oct 2011 15:13:46 -0000
*************** struct trace_status
*** 79,84 ****
--- 79,85 ----
    /* This is true if the value of the running field is known.  */
    int running_known;
  
+   /* This is true when the trace experiment is actually running.  */
    int running;
  
    enum trace_stop_reason stop_reason;
*************** struct trace_status
*** 88,96 ****
       stop.  */
    int stopping_tracepoint;
  
!   /* If stop_reason is tracepoint_error, this is a human-readable
!      string that describes the error that happened on the target.  */
!   char *error_desc;
  
    /* Number of traceframes currently in the buffer.  */
  
--- 89,98 ----
       stop.  */
    int stopping_tracepoint;
  
!   /* If stop_reason is tstop_command or tracepoint_error, this is a
!      human-readable string that describes the reason for the stop in
!      more detail.  */
!   char *stop_desc;
  
    /* Number of traceframes currently in the buffer.  */
  
*************** struct trace_status
*** 117,122 ****
--- 119,132 ----
       target does not report a value, assume 0.  */
  
    int circular_buffer;
+ 
+   char *user_name;
+ 
+   char *notes;
+ 
+   LONGEST start_time;
+ 
+   LONGEST stop_time;
  };
  
  struct trace_status *current_trace_status (void);
*************** struct uploaded_tp
*** 154,159 ****
--- 164,173 ----
    /* List of original strings defining the tracepoint's actions.  */
    VEC(char_ptr) *cmd_strings;
  
+   int hit_count;
+ 
+   ULONGEST traceframe_usage;
+ 
    struct uploaded_tp *next;
  };
  
*************** extern int encode_source_string (int num
*** 226,231 ****
--- 240,248 ----
  
  extern void parse_trace_status (char *line, struct trace_status *ts);
  
+ extern void parse_tracepoint_status (char *p, struct breakpoint *tp,
+ 				     struct uploaded_tp *utp);
+ 
  extern void parse_tracepoint_definition (char *line,
  					 struct uploaded_tp **utpp);
  extern void parse_tsv_definition (char *line, struct uploaded_tsv **utsvp);
*************** extern void merge_uploaded_trace_state_v
*** 238,245 ****
  
  extern void disconnect_tracing (int from_tty);
  
! extern void start_tracing (void);
! extern void stop_tracing (void);
  
  extern void trace_status_mi (int on_stop);
  
--- 255,262 ----
  
  extern void disconnect_tracing (int from_tty);
  
! extern void start_tracing (char *notes);
! extern void stop_tracing (char *notes);
  
  extern void trace_status_mi (int on_stop);
  
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.878
diff -p -r1.878 gdb.texinfo
*** doc/gdb.texinfo	13 Oct 2011 14:50:08 -0000	1.878
--- doc/gdb.texinfo	17 Oct 2011 15:13:47 -0000
*************** Cnt ID         Enb Address            Wh
*** 10753,10772 ****
  @subsection Starting and Stopping Trace Experiments
  
  @table @code
! @kindex tstart
  @cindex start a new trace experiment
  @cindex collected data discarded
  @item tstart
! This command takes no arguments.  It starts the trace experiment, and
! begins collecting data.  This has the side effect of discarding all
! the data collected in the trace buffer during the previous trace
! experiment.
  
! @kindex tstop
  @cindex stop a running trace experiment
  @item tstop
! This command takes no arguments.  It ends the trace experiment, and
! stops collecting data.
  
  @strong{Note}: a trace experiment and data collection may stop
  automatically if any tracepoint's passcount is reached
--- 10753,10779 ----
  @subsection Starting and Stopping Trace Experiments
  
  @table @code
! @kindex tstart [ @var{notes} ]
  @cindex start a new trace experiment
  @cindex collected data discarded
  @item tstart
! This command starts the trace experiment, and begins collecting data.
! It has the side effect of discarding all the data collected in the
! trace buffer during the previous trace experiment.  If any arguments
! are supplied, they are taken as a note and stored with the trace
! experiment's state.  The notes may be arbitrary text, and are
! especially useful with disconnected tracing in a multi-user context;
! the notes can explain what the trace is doing, supply user contact
! information, and so forth.
  
! @kindex tstop [ @var{notes} ]
  @cindex stop a running trace experiment
  @item tstop
! This command stops the trace experiment.  If any arguments are
! supplied, they are recorded with the experiment as a note.  This is
! useful if you are stopping a trace started by someone else, for
! instance if the trace is interfering with the system's behavior and
! needs to be stopped quickly.
  
  @strong{Note}: a trace experiment and data collection may stop
  automatically if any tracepoint's passcount is reached
*************** for instance if you are looking at frame
*** 10870,10875 ****
--- 10877,10909 ----
  
  @end table
  
+ @table @code
+ @item set trace-user @var{text}
+ @kindex set trace-user
+ 
+ @item show trace-user
+ @kindex show trace-user
+ 
+ @item set trace-notes @var{text}
+ @kindex set trace-notes
+ Set the trace run's notes.
+ 
+ @item show trace-notes
+ @kindex show trace-notes
+ Show the trace run's notes.
+ 
+ @item set trace-stop-notes @var{text}
+ @kindex set trace-stop-notes
+ Set the trace run's stop notes.  The handling of the note is as for
+ @code{tstop} arguments; the set command is convenient way to fix a
+ stop note that is mistaken or incomplete.
+ 
+ @item show trace-stop-notes
+ @kindex show trace-stop-notes
+ Show the trace run's stop notes.
+ 
+ @end table
+ 
  @node Tracepoint Restrictions
  @subsection Tracepoint Restrictions
  
*************** the command by a @samp{,}, not a @samp{:
*** 34710,34715 ****
--- 34744,34751 ----
  conventions above.  Please don't use this packet as a model for new
  packets.)
  
+ @item QTNotes
+ @item qTP
  @item QTSave
  @item qTsP
  @item qTsV
*************** explanations as one of the optional fiel
*** 35268,35275 ****
  @item tnotrun:0
  No trace has been run yet.
  
! @item tstop:0
! The trace was stopped by a user-originated stop command.
  
  @item tfull:0
  The trace stopped because the trace buffer filled up.
--- 35304,35314 ----
  @item tnotrun:0
  No trace has been run yet.
  
! @item tstop[:@var{text}]:0
! The trace was stopped by a user-originated stop command.  The optional
! @var{text} field is a user-supplied string supplied as part of the
! stop command (for instance, an explanation of why the trace was
! stopped manually).  It is hex-encoded.
  
  @item tfull:0
  The trace stopped because the trace buffer filled up.
*************** that the trace run will stop.
*** 35325,35330 ****
--- 35364,35385 ----
  
  @end table
  
+ @item qTP:@var{tp}:@var{addr}
+ @cindex tracepoint status, remote request
+ @cindex @samp{qTP} packet
+ Ask the stub for the current state of tracepoint number @var{tp} at
+ address @var{addr}.
+ 
+ Replies:
+ @table @samp
+ @item V@var{hits}:@var{usage}
+ The tracepoint has been hit @var{hits} times so far during the trace
+ run, and accounts for @var{usage} in the trace buffer.  Note that
+ @code{while-stepping} steps are not counted as separate hits, but the
+ steps' space consumption is added into the usage number.
+ 
+ @end table
+ 
  @item qTV:@var{var}
  @cindex trace state variable value, remote request
  @cindex @samp{qTV} packet
*************** available.
*** 35418,35423 ****
--- 35473,35483 ----
  This packet directs the target to use a circular trace buffer if
  @var{value} is 1, or a linear buffer if the value is 0.
  
+ @item QTNotes:@r{[}@var{type}:@var{text}@r{]}@r{[};@var{type}:@var{text}@r{]}@dots{}
+ This packet adds optional textual notes to the trace run.  Allowable
+ types include @code{user}, @code{notes}, and @code{tstop}, the
+ @var{text} fields are arbitrary strings, hex-encoded.
+ 
  @end table
  
  @subsection Relocate instruction reply packet
Index: gdbserver/tracepoint.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/tracepoint.c,v
retrieving revision 1.27
diff -p -r1.27 tracepoint.c
*** gdbserver/tracepoint.c	15 Sep 2011 22:54:13 -0000	1.27
--- gdbserver/tracepoint.c	17 Oct 2011 15:13:47 -0000
*************** struct tracepoint
*** 623,628 ****
--- 623,631 ----
       Note that while-stepping steps are not counted as "hits".  */
    long hit_count;
  
+   /* Cached sum of the sizes of traceframes created by this point.  */
+   long traceframe_usage;
+ 
    CORE_ADDR compiled_cond;
  
    /* Link to the next tracepoint in the list.  */
*************** static const char *tracing_stop_reason =
*** 1129,1134 ****
--- 1132,1150 ----
  
  static int tracing_stop_tpnum;
  
+ /* 64-bit timestamps for the trace run's start and finish.  */
+ 
+ long long start_time;
+ long long stop_time;
+ 
+ /* The (optional) name of the user that started the run.  */
+ 
+ char *tracing_user_name;
+ 
+ /* User-supplied text describing the run for the benefit of other users.  */
+ 
+ char *tracing_notes;
+ 
  #endif
  
  /* Functions local to this file.  */
*************** static void do_action_at_tracepoint (str
*** 1244,1249 ****
--- 1260,1267 ----
  static struct tracepoint *fast_tracepoint_from_ipa_tpoint_address (CORE_ADDR);
  #endif
  
+ static LONGEST get_timestamp (void);
+ 
  #if defined(__GNUC__)
  #  define memory_barrier() asm volatile ("" : : : "memory")
  #else
*************** cmd_qtstart (char *packet)
*** 2788,2793 ****
--- 2806,2812 ----
      {
        /* Ensure all the hit counts start at zero.  */
        tpoint->hit_count = 0;
+       tpoint->traceframe_usage = 0;
  
        if (tpoint->type == trap_tracepoint)
  	{
*************** cmd_qtstart (char *packet)
*** 2912,2917 ****
--- 2931,2937 ----
    trace_buffer_is_full = 0;
    expr_eval_result = expr_eval_no_error;
    error_tracepoint = NULL;
+   start_time = get_timestamp ();
  
    /* Tracing is now active, hits will now start being logged.  */
    tracing = 1;
*************** stop_tracing (void)
*** 2981,2986 ****
--- 3001,3007 ----
  	fatal ("Error clearing tracing variable in lib");
      }
  
+   stop_time = get_timestamp ();
    tracing_stop_reason = "t???";
    tracing_stop_tpnum = 0;
    if (stopping_tracepoint)
*************** cmd_qtstatus (char *packet)
*** 3162,3167 ****
--- 3183,3201 ----
  {
    char *stop_reason_rsp = NULL;
  
+   char *buf1, *buf2, *str;
+   int slen;
+ 
+   str = (tracing_user_name ? tracing_user_name : "");
+   slen = strlen (str);
+   buf1 = (char *) alloca (slen * 2 + 1);
+   hexify (buf1, str, slen);
+ 
+   str = (tracing_notes ? tracing_notes : "");
+   slen = strlen (str);
+   buf2 = (char *) alloca (slen * 2 + 1);
+   hexify (buf2, str, slen);
+ 
    trace_debug ("Returning trace status as %d, stop reason %s",
  	       tracing, tracing_stop_reason);
  
*************** cmd_qtstatus (char *packet)
*** 3199,3211 ****
  	   "tframes:%x;tcreated:%x;"
  	   "tfree:%x;tsize:%s;"
  	   "circular:%d;"
! 	   "disconn:%d",
  	   tracing ? 1 : 0,
  	   stop_reason_rsp, tracing_stop_tpnum,
  	   traceframe_count, traceframes_created,
  	   free_space (), phex_nz (trace_buffer_hi - trace_buffer_lo, 0),
  	   circular_trace_buffer,
! 	   disconnected_tracing);
  }
  
  /* State variables to help return all the tracepoint bits.  */
--- 3233,3276 ----
  	   "tframes:%x;tcreated:%x;"
  	   "tfree:%x;tsize:%s;"
  	   "circular:%d;"
! 	   "disconn:%d"
! 	   "starttime:%llx;stoptime:%llx;"
! 	   "username:%s:;notes:%s:",
  	   tracing ? 1 : 0,
  	   stop_reason_rsp, tracing_stop_tpnum,
  	   traceframe_count, traceframes_created,
  	   free_space (), phex_nz (trace_buffer_hi - trace_buffer_lo, 0),
  	   circular_trace_buffer,
! 	   disconnected_tracing,
! 	   start_time, stop_time,
! 	   buf1, buf2);
! }
! 
! static void
! cmd_qtp (char *own_buf)
! {
!   ULONGEST num, addr;
!   struct tracepoint *tpoint;
!   char *packet = own_buf;
! 
!   packet += strlen ("qTP:");
! 
!   packet = unpack_varlen_hex (packet, &num);
!   ++packet; /* skip a colon */
!   packet = unpack_varlen_hex (packet, &addr);
! 
!   /* See if we already have this tracepoint.  */
!   tpoint = find_tracepoint (num, addr);
! 
!   if (!tpoint)
!     {
!       trace_debug ("Tracepoint error: tracepoint %d at 0x%s not found",
! 		   (int) num, paddress (addr));
!       write_enn (own_buf);
!       return;
!     }
! 
!   sprintf (own_buf, "V%lx:%lx", tpoint->hit_count, tpoint->traceframe_usage);
  }
  
  /* State variables to help return all the tracepoint bits.  */
*************** cmd_bigqtbuffer (char *own_buf)
*** 3510,3515 ****
--- 3575,3636 ----
      write_enn (own_buf);
  }
  
+ static void
+ cmd_qtnotes (char *own_buf)
+ {
+   size_t nbytes;
+   char *saved, *user, *notes, *tstop;
+   char *packet = own_buf;
+ 
+   packet += strlen ("QTNotes:");
+ 
+   while (*packet)
+     {
+       if (strncmp ("user:", packet, strlen ("user:")) == 0)
+ 	{
+ 	  packet += strlen ("user:");
+ 	  saved = packet;
+ 	  packet = strchr (packet, ';');
+ 	  nbytes = (packet - saved) / 2;
+ 	  user = xmalloc (nbytes + 1);
+ 	  nbytes = unhexify (user, saved, nbytes);
+ 	  user[nbytes] = '\0';
+ 	  ++packet; /* skip the semicolon */
+ 	  trace_debug ("User is '%s'", user);
+ 	  tracing_user_name = user;
+ 	}
+       else if (strncmp ("notes:", packet, strlen ("notes:")) == 0)
+ 	{
+ 	  packet += strlen ("notes:");
+ 	  saved = packet;
+ 	  packet = strchr (packet, ';');
+ 	  nbytes = (packet - saved) / 2;
+ 	  notes = xmalloc (nbytes + 1);
+ 	  nbytes = unhexify (notes, saved, nbytes);
+ 	  notes[nbytes] = '\0';
+ 	  ++packet; /* skip the semicolon */
+ 	  trace_debug ("Notes is '%s'", notes);
+ 	  tracing_notes = notes;
+ 	}
+       else if (strncmp ("tstop:", packet, strlen ("tstop:")) == 0)
+ 	{
+ 	  saved = packet;
+ 	  packet = strchr (packet, ';');
+ 	  nbytes = (packet - saved) / 2;
+ 	  tstop = xmalloc (nbytes + 1);
+ 	  nbytes = unhexify (tstop, saved, nbytes);
+ 	  tstop[nbytes] = '\0';
+ 	  ++packet; /* skip the semicolon */
+ 	  trace_debug ("tstop reason is '%s'", tstop);
+ 	  tracing_stop_reason = tstop;
+ 	}
+       else
+ 	break;
+     }
+ 
+   write_ok (own_buf);
+ }
+ 
  int
  handle_tracepoint_general_set (char *packet)
  {
*************** handle_tracepoint_general_set (char *pac
*** 3574,3579 ****
--- 3695,3705 ----
        cmd_bigqtbuffer (packet);
        return 1;
      }
+   else if (strncmp ("QTNotes:", packet, strlen ("QTNotes:")) == 0)
+     {
+       cmd_qtnotes (packet);
+       return 1;
+     }
  
    return 0;
  }
*************** handle_tracepoint_query (char *packet)
*** 3586,3591 ****
--- 3712,3722 ----
        cmd_qtstatus (packet);
        return 1;
      }
+   else if (strncmp ("qTP:", packet, strlen ("qTP:")) == 0)
+     {
+       cmd_qtp (packet);
+       return 1;
+     }
    else if (strcmp ("qTfP", packet) == 0)
      {
        cmd_qtfp (packet);
*************** initialize_tracepoint_ftlib (void)
*** 7635,7641 ****
  #endif /* IN_PROCESS_AGENT */
  
  static LONGEST
! tsv_get_timestamp (void)
  {
     struct timeval tv;
  
--- 7766,7772 ----
  #endif /* IN_PROCESS_AGENT */
  
  static LONGEST
! get_timestamp (void)
  {
     struct timeval tv;
  
*************** initialize_tracepoint (void)
*** 7659,7665 ****
       variable numbered 1, it will be renumbered.)  */
    create_trace_state_variable (1, 0);
    set_trace_state_variable_name (1, "trace_timestamp");
!   set_trace_state_variable_getter (1, tsv_get_timestamp);
  
  #ifdef IN_PROCESS_AGENT
    {
--- 7790,7796 ----
       variable numbered 1, it will be renumbered.)  */
    create_trace_state_variable (1, 0);
    set_trace_state_variable_name (1, "trace_timestamp");
!   set_trace_state_variable_getter (1, get_timestamp);
  
  #ifdef IN_PROCESS_AGENT
    {
Index: mi/mi-main.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-main.c,v
retrieving revision 1.207
diff -p -r1.207 mi-main.c
*** mi/mi-main.c	3 Oct 2011 21:38:31 -0000	1.207
--- mi/mi-main.c	17 Oct 2011 15:13:48 -0000
*************** mi_cmd_trace_save (char *command, char *
*** 2490,2496 ****
  void
  mi_cmd_trace_start (char *command, char **argv, int argc)
  {
!   start_tracing ();
  }
  
  void
--- 2490,2496 ----
  void
  mi_cmd_trace_start (char *command, char **argv, int argc)
  {
!   start_tracing (NULL);
  }
  
  void
*************** mi_cmd_trace_status (char *command, char
*** 2502,2508 ****
  void
  mi_cmd_trace_stop (char *command, char **argv, int argc)
  {
!   stop_tracing ();
    trace_status_mi (1);
  }
  
--- 2502,2508 ----
  void
  mi_cmd_trace_stop (char *command, char **argv, int argc)
  {
!   stop_tracing (NULL);
    trace_status_mi (1);
  }
  

             reply	other threads:[~2011-10-17 16:00 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-10-17 16:27 Stan Shebs [this message]
2011-10-17 16:39 ` Eli Zaretskii
2011-10-18  1:44   ` Stan Shebs
2011-11-03 15:18 ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4E9C5112.9070705@mentor.com \
    --to=stan_shebs@mentor.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox