* [PATCH] Tracing notes and metadata
@ 2011-10-17 16:27 Stan Shebs
2011-10-17 16:39 ` Eli Zaretskii
2011-11-03 15:18 ` Tom Tromey
0 siblings, 2 replies; 4+ messages in thread
From: Stan Shebs @ 2011-10-17 16:27 UTC (permalink / raw)
To: gdb-patches
[-- 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);
}
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] Tracing notes and metadata
2011-10-17 16:27 [PATCH] Tracing notes and metadata Stan Shebs
@ 2011-10-17 16:39 ` Eli Zaretskii
2011-10-18 1:44 ` Stan Shebs
2011-11-03 15:18 ` Tom Tromey
1 sibling, 1 reply; 4+ messages in thread
From: Eli Zaretskii @ 2011-10-17 16:39 UTC (permalink / raw)
To: Stan Shebs; +Cc: gdb-patches
> Date: Mon, 17 Oct 2011 09:00:18 -0700
> From: Stan Shebs <stan_shebs@mentor.com>
>
> 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.
The documentation part is okay, but please add some overview of the
notes, to serve as the glue to the description of the commands. As I
read the patch, I was wondering whether there's only one note that can
be set by either "tstart" or "tstop" (and then what happens if you
give arguments to "tstop" when "tstart" already provided a note?), or
two separate and independent notes (in which case why do we have
"trace-stop-notes", but no "trace-start-notes"?). Instead of
disclosing all this piecemeal and leaving the reader with a reasonable
doubt, why not explain it once and for all?
Btw, didn't the socializing parties ask you for a way to _add_ to an
existing note, rather than overwriting it? The way you designed it,
fixing a single typo requires retyping (or copy/pasting) the whole
thing, which sounds inconvenient.
Thanks.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] Tracing notes and metadata
2011-10-17 16:39 ` Eli Zaretskii
@ 2011-10-18 1:44 ` Stan Shebs
0 siblings, 0 replies; 4+ messages in thread
From: Stan Shebs @ 2011-10-18 1:44 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
On 10/17/2011 09:29 AM, Eli Zaretskii wrote:
>> Date: Mon, 17 Oct 2011 09:00:18 -0700
>> From: Stan Shebs<stan_shebs@mentor.com>
>>
>> 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.
> The documentation part is okay, but please add some overview of the
> notes, to serve as the glue to the description of the commands. As I
> read the patch, I was wondering whether there's only one note that can
> be set by either "tstart" or "tstop" (and then what happens if you
> give arguments to "tstop" when "tstart" already provided a note?), or
> two separate and independent notes (in which case why do we have
> "trace-stop-notes", but no "trace-start-notes"?). Instead of
> disclosing all this piecemeal and leaving the reader with a reasonable
> doubt, why not explain it once and for all?
OK, needs more explanation then. :-) The tstart note is the summary of
the trace run as a whole, while the stop note only applies if the trace
was manually stopped via tstop, vs stopping due to trace buffer full,
bytecode dividing by zero, etc. In practice, one would only expect to
supply a stop note if the trace had to be manually stopped by someone
else ("tstop I needed to stop your run so I could test my workaround for
bug 12043 -sts"), so the original person running the trace has an
explanation of what happened - and can interpret the
possibly-incomplete trace results accordingly.
> Btw, didn't the socializing parties ask you for a way to _add_ to an
> existing note, rather than overwriting it? The way you designed it,
> fixing a single typo requires retyping (or copy/pasting) the whole
> thing, which sounds inconvenient.
>
No, you're the first person to mention adding actually. I think the
mental model is that the notes are typically one-liners, and we do have
line-editing capability available from readline. I think if things
really needed to be much more elaborate in a multi-user setting, the
users would set up a wiki or virtual signup sheets or some such, and at
that point it gets generally out of scope for GDB. ("tstart
http://signup.intranet.com/34129")
Stan
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] Tracing notes and metadata
2011-10-17 16:27 [PATCH] Tracing notes and metadata Stan Shebs
2011-10-17 16:39 ` Eli Zaretskii
@ 2011-11-03 15:18 ` Tom Tromey
1 sibling, 0 replies; 4+ messages in thread
From: Tom Tromey @ 2011-11-03 15:18 UTC (permalink / raw)
To: Stan Shebs; +Cc: gdb-patches
>>>>> "Stan" == Stan Shebs <stan_shebs@mentor.com> writes:
Stan> This patch brings social networking to GDB! :-)
Your IPO awaits.
Stan> The patch still needs testsuite and NEWS, but considering the user
Stan> interface tinkering, it seemed like a good idea to solicit feedback
Stan> before committing to all the details.
I read through this. The UI changes are fine by me. I have a couple
nits about the patch, but that is all.
Stan> int circular_buffer;
Stan> +
Stan> + char *user_name;
Stan> +
Stan> + char *notes;
Stan> +
Stan> + LONGEST start_time;
Stan> +
Stan> + LONGEST stop_time;
Stan> };
I'd like comments on new fields.
It would be nice to add Usage lines now to the tstart and tstop help
text; the help text needs a little update anyhow to account for the new
feature.
Tom
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-11-03 15:18 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-17 16:27 [PATCH] Tracing notes and metadata Stan Shebs
2011-10-17 16:39 ` Eli Zaretskii
2011-10-18 1:44 ` Stan Shebs
2011-11-03 15:18 ` Tom Tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox