* NEWS: Mention tracepoint additions.
* 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): Similarly. (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. * tracepoint.c (struct tracepoint): New field traceframe_usage. (tracing_start_time): New global. (tracing_stop_time): New global. (tracing_user_name): New global. (tracing_notes): New global. (tracing_stop_note): 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. * gdb.texinfo (Starting and Stopping Trace Experiments): Document note-related options and variables. (Tracepoint Packets): Document packet changes. * gdb.trace/tstatus.exp: New. * gdb.trace/actions.c: Include string.h.
This commit is contained in:
parent
9866a1803a
commit
f196051f5e
@ -1,3 +1,46 @@
|
||||
2011-11-20 Stan Shebs <stan@codesourcery.com>
|
||||
|
||||
* NEWS: Mention tracepoint additions.
|
||||
* 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): Similarly.
|
||||
(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.
|
||||
|
||||
2011-11-20 Sanjoy Das <sdas@igalia.com>
|
||||
|
||||
* jit.c: Include regcache.h.
|
||||
|
35
gdb/NEWS
35
gdb/NEWS
@ -133,6 +133,17 @@ collect[/s] EXPRESSIONS
|
||||
string. An optional integer following the "/s" sets a bound on the
|
||||
number of bytes that will be collected.
|
||||
|
||||
tstart [NOTES]
|
||||
The trace start command now interprets any supplied arguments as a
|
||||
note to be recorded with the trace run, with an effect similar to
|
||||
setting the variable trace-notes.
|
||||
|
||||
tstop [NOTES]
|
||||
The trace stop command now interprets any arguments as a note to be
|
||||
mentioned along with the tstatus report that the trace was stopped
|
||||
with a command. The effect is similar to setting the variable
|
||||
trace-stop-notes.
|
||||
|
||||
* Tracepoints can now be enabled and disabled at any time after a trace
|
||||
experiment has been started using the standard "enable" and "disable"
|
||||
commands. It is now possible to start a trace experiment with no enabled
|
||||
@ -176,6 +187,22 @@ show basenames-may-differ
|
||||
If not set (the default), all source files are assumed to have just
|
||||
one base name, and gdb will do file name comparisons more efficiently.
|
||||
|
||||
set trace-user
|
||||
show trace-user
|
||||
set trace-notes
|
||||
show trace-notes
|
||||
Set a user name and notes for the current and any future trace runs.
|
||||
This is useful for long-running and/or disconnected traces, to
|
||||
inform others (or yourself) as to who is running the trace, supply
|
||||
contact information, or otherwise explain what is going on.
|
||||
|
||||
set trace-stop-notes
|
||||
show trace-stop-notes
|
||||
Set a note attached to the trace run, that is displayed when the
|
||||
trace has been stopped by a tstop command. This is useful for
|
||||
instance as an explanation, if you are stopping a trace run that was
|
||||
started by someone else.
|
||||
|
||||
* New remote packets
|
||||
|
||||
QTEnable
|
||||
@ -186,6 +213,14 @@ QTDisable
|
||||
|
||||
Dynamically disable a tracepoint in a started trace experiment.
|
||||
|
||||
QTNotes
|
||||
|
||||
Set the user and notes of the trace run.
|
||||
|
||||
qTP
|
||||
|
||||
Query the current status of a tracepoint.
|
||||
|
||||
qTMinFTPILen
|
||||
|
||||
Query the minimum length of instruction at which a fast tracepoint may
|
||||
|
@ -4879,6 +4879,8 @@ print_one_breakpoint_location (struct breakpoint *b,
|
||||
/* 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 ");
|
||||
@ -4903,6 +4905,18 @@ print_one_breakpoint_location (struct breakpoint *b,
|
||||
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)
|
||||
{
|
||||
@ -12904,6 +12918,10 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
|
||||
"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;
|
||||
}
|
||||
|
||||
|
@ -710,6 +710,10 @@ struct tracepoint
|
||||
/* 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;
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2011-11-20 Stan Shebs <stan@codesourcery.com>
|
||||
|
||||
* gdb.texinfo (Starting and Stopping Trace Experiments): Document
|
||||
note-related options and variables.
|
||||
(Tracepoint Packets): Document packet changes.
|
||||
|
||||
2011-11-20 Sanjoy Das <sdas@igalia.com>
|
||||
|
||||
* gdb.texinfo (JIT Interface): Add documentation on writing and
|
||||
|
@ -10902,20 +10902,27 @@ Cnt ID Enb Address What
|
||||
@subsection Starting and Stopping Trace Experiments
|
||||
|
||||
@table @code
|
||||
@kindex tstart
|
||||
@kindex tstart [ @var{notes} ]
|
||||
@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.
|
||||
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
|
||||
@kindex tstop [ @var{notes} ]
|
||||
@cindex stop a running trace experiment
|
||||
@item tstop
|
||||
This command takes no arguments. It ends the trace experiment, and
|
||||
stops collecting data.
|
||||
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
|
||||
@ -11019,6 +11026,33 @@ for instance if you are looking at frames from a trace file.
|
||||
|
||||
@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
|
||||
|
||||
@ -35115,6 +35149,8 @@ the command by a @samp{,}, not a @samp{:}, contrary to the naming
|
||||
conventions above. Please don't use this packet as a model for new
|
||||
packets.)
|
||||
|
||||
@item QTNotes
|
||||
@item qTP
|
||||
@item QTSave
|
||||
@item qTsP
|
||||
@item qTsV
|
||||
@ -35697,8 +35733,11 @@ explanations as one of the optional fields:
|
||||
@item tnotrun:0
|
||||
No trace has been run yet.
|
||||
|
||||
@item tstop:0
|
||||
The trace was stopped by a user-originated stop command.
|
||||
@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.
|
||||
@ -35754,6 +35793,22 @@ that the trace run will stop.
|
||||
|
||||
@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
|
||||
@ -35847,6 +35902,11 @@ available.
|
||||
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
|
||||
|
@ -1,3 +1,20 @@
|
||||
2011-11-17 Stan Shebs <stan@codesourcery.com>
|
||||
|
||||
* tracepoint.c (struct tracepoint): New field traceframe_usage.
|
||||
(tracing_start_time): New global.
|
||||
(tracing_stop_time): New global.
|
||||
(tracing_user_name): New global.
|
||||
(tracing_notes): New global.
|
||||
(tracing_stop_note): 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.
|
||||
|
||||
2011-11-14 Stan Shebs <stan@codesourcery.com>
|
||||
Kwok Cheung Yeung <kcy@codesourcery.com>
|
||||
|
||||
|
@ -632,6 +632,9 @@ struct tracepoint
|
||||
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. */
|
||||
@ -1144,6 +1147,27 @@ static const char *tracing_stop_reason = "tnotrun";
|
||||
|
||||
static int tracing_stop_tpnum;
|
||||
|
||||
/* 64-bit timestamps for the trace run's start and finish, expressed
|
||||
in microseconds from the Unix epoch. */
|
||||
|
||||
LONGEST tracing_start_time;
|
||||
LONGEST tracing_stop_time;
|
||||
|
||||
/* The (optional) user-supplied name of the user that started the run.
|
||||
This is an arbitrary string, and may be NULL. */
|
||||
|
||||
char *tracing_user_name;
|
||||
|
||||
/* Optional user-supplied text describing the run. This is
|
||||
an arbitrary string, and may be NULL. */
|
||||
|
||||
char *tracing_notes;
|
||||
|
||||
/* Optional user-supplied text explaining a tstop command. This is an
|
||||
arbitrary string, and may be NULL. */
|
||||
|
||||
char *tracing_stop_note;
|
||||
|
||||
#endif
|
||||
|
||||
/* Functions local to this file. */
|
||||
@ -1266,6 +1290,8 @@ static void download_tracepoint (struct tracepoint *);
|
||||
static int install_fast_tracepoint (struct tracepoint *, char *errbuf);
|
||||
#endif
|
||||
|
||||
static LONGEST get_timestamp (void);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# define memory_barrier() asm volatile ("" : : : "memory")
|
||||
#else
|
||||
@ -3027,6 +3053,7 @@ cmd_qtstart (char *packet)
|
||||
{
|
||||
/* Ensure all the hit counts start at zero. */
|
||||
tpoint->hit_count = 0;
|
||||
tpoint->traceframe_usage = 0;
|
||||
|
||||
if (tpoint->type == trap_tracepoint)
|
||||
{
|
||||
@ -3103,6 +3130,7 @@ cmd_qtstart (char *packet)
|
||||
trace_buffer_is_full = 0;
|
||||
expr_eval_result = expr_eval_no_error;
|
||||
error_tracepoint = NULL;
|
||||
tracing_start_time = get_timestamp ();
|
||||
|
||||
/* Tracing is now active, hits will now start being logged. */
|
||||
tracing = 1;
|
||||
@ -3172,6 +3200,7 @@ stop_tracing (void)
|
||||
fatal ("Error clearing tracing variable in lib");
|
||||
}
|
||||
|
||||
tracing_stop_time = get_timestamp ();
|
||||
tracing_stop_reason = "t???";
|
||||
tracing_stop_tpnum = 0;
|
||||
if (stopping_tracepoint)
|
||||
@ -3352,6 +3381,26 @@ static void
|
||||
cmd_qtstatus (char *packet)
|
||||
{
|
||||
char *stop_reason_rsp = NULL;
|
||||
char *buf1, *buf2, *buf3, *str;
|
||||
int slen;
|
||||
|
||||
/* Translate the plain text of the notes back into hex for
|
||||
transmission. */
|
||||
|
||||
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);
|
||||
|
||||
str = (tracing_stop_note ? tracing_stop_note : "");
|
||||
slen = strlen (str);
|
||||
buf3 = (char *) alloca (slen * 2 + 1);
|
||||
hexify (buf3, str, slen);
|
||||
|
||||
trace_debug ("Returning trace status as %d, stop reason %s",
|
||||
tracing, tracing_stop_reason);
|
||||
@ -3368,7 +3417,7 @@ cmd_qtstatus (char *packet)
|
||||
stop_reason_rsp = (char *) tracing_stop_reason;
|
||||
|
||||
/* The user visible error string in terror needs to be hex encoded.
|
||||
We leave it as plain string in `tracepoint_stop_reason' to ease
|
||||
We leave it as plain string in `tracing_stop_reason' to ease
|
||||
debugging. */
|
||||
if (strncmp (stop_reason_rsp, "terror:", strlen ("terror:")) == 0)
|
||||
{
|
||||
@ -3384,19 +3433,58 @@ cmd_qtstatus (char *packet)
|
||||
convert_int_to_ascii ((gdb_byte *) result_name, p, strlen (result_name));
|
||||
}
|
||||
|
||||
/* If this was a forced stop, include any stop note that was supplied. */
|
||||
if (strcmp (stop_reason_rsp, "tstop") == 0)
|
||||
{
|
||||
stop_reason_rsp = alloca (strlen ("tstop:") + strlen (buf3) + 1);
|
||||
strcpy (stop_reason_rsp, "tstop:");
|
||||
strcat (stop_reason_rsp, buf3);
|
||||
}
|
||||
|
||||
sprintf (packet,
|
||||
"T%d;"
|
||||
"%s:%x;"
|
||||
"tframes:%x;tcreated:%x;"
|
||||
"tfree:%x;tsize:%s;"
|
||||
"circular:%d;"
|
||||
"disconn:%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);
|
||||
disconnected_tracing,
|
||||
tracing_start_time, tracing_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. */
|
||||
@ -3710,6 +3798,63 @@ cmd_bigqtbuffer (char *own_buf)
|
||||
write_enn (own_buf);
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_qtnotes (char *own_buf)
|
||||
{
|
||||
size_t nbytes;
|
||||
char *saved, *user, *notes, *stopnote;
|
||||
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)
|
||||
{
|
||||
packet += strlen ("tstop:");
|
||||
saved = packet;
|
||||
packet = strchr (packet, ';');
|
||||
nbytes = (packet - saved) / 2;
|
||||
stopnote = xmalloc (nbytes + 1);
|
||||
nbytes = unhexify (stopnote, saved, nbytes);
|
||||
stopnote[nbytes] = '\0';
|
||||
++packet; /* skip the semicolon */
|
||||
trace_debug ("tstop note is '%s'", stopnote);
|
||||
tracing_stop_note = stopnote;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
write_ok (own_buf);
|
||||
}
|
||||
|
||||
int
|
||||
handle_tracepoint_general_set (char *packet)
|
||||
{
|
||||
@ -3774,6 +3919,11 @@ handle_tracepoint_general_set (char *packet)
|
||||
cmd_bigqtbuffer (packet);
|
||||
return 1;
|
||||
}
|
||||
else if (strncmp ("QTNotes:", packet, strlen ("QTNotes:")) == 0)
|
||||
{
|
||||
cmd_qtnotes (packet);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -3786,6 +3936,11 @@ handle_tracepoint_query (char *packet)
|
||||
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);
|
||||
@ -8049,8 +8204,12 @@ initialize_tracepoint_ftlib (void)
|
||||
|
||||
#endif /* IN_PROCESS_AGENT */
|
||||
|
||||
/* Return a timestamp, expressed as microseconds of the usual Unix
|
||||
time. (As the result is a 64-bit number, it will not overflow any
|
||||
time soon.) */
|
||||
|
||||
static LONGEST
|
||||
tsv_get_timestamp (void)
|
||||
get_timestamp (void)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
@ -8074,7 +8233,7 @@ initialize_tracepoint (void)
|
||||
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);
|
||||
set_trace_state_variable_getter (1, get_timestamp);
|
||||
|
||||
#ifdef IN_PROCESS_AGENT
|
||||
{
|
||||
|
@ -2490,7 +2490,7 @@ mi_cmd_trace_save (char *command, char **argv, int argc)
|
||||
void
|
||||
mi_cmd_trace_start (char *command, char **argv, int argc)
|
||||
{
|
||||
start_tracing ();
|
||||
start_tracing (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2502,7 +2502,7 @@ mi_cmd_trace_status (char *command, char **argv, int argc)
|
||||
void
|
||||
mi_cmd_trace_stop (char *command, char **argv, int argc)
|
||||
{
|
||||
stop_tracing ();
|
||||
stop_tracing (NULL);
|
||||
trace_status_mi (1);
|
||||
}
|
||||
|
||||
|
94
gdb/remote.c
94
gdb/remote.c
@ -10214,6 +10214,53 @@ remote_get_trace_status (struct trace_status *ts)
|
||||
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)
|
||||
{
|
||||
@ -10485,6 +10532,51 @@ remote_get_min_fast_tracepoint_insn_len (void)
|
||||
}
|
||||
}
|
||||
|
||||
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++ = ';';
|
||||
}
|
||||
/* Ensure the buffer is terminated. */
|
||||
*buf = '\0';
|
||||
|
||||
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)
|
||||
{
|
||||
@ -10565,6 +10657,7 @@ Specify the serial device it is connected to\n\
|
||||
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
|
||||
@ -10577,6 +10670,7 @@ Specify the serial device it is connected to\n\
|
||||
remote_ops.to_get_min_fast_tracepoint_insn_len = remote_get_min_fast_tracepoint_insn_len;
|
||||
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;
|
||||
|
@ -682,6 +682,7 @@ update_current_target (void)
|
||||
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);
|
||||
@ -692,6 +693,7 @@ update_current_target (void)
|
||||
INHERIT (to_get_min_fast_tracepoint_insn_len, 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);
|
||||
@ -873,6 +875,9 @@ update_current_target (void)
|
||||
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);
|
||||
@ -903,6 +908,9 @@ update_current_target (void)
|
||||
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);
|
||||
|
13
gdb/target.h
13
gdb/target.h
@ -713,6 +713,9 @@ struct target_ops
|
||||
/* 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);
|
||||
|
||||
@ -749,6 +752,10 @@ struct target_ops
|
||||
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
|
||||
@ -1508,6 +1515,9 @@ extern int target_search_memory (CORE_ADDR start_addr,
|
||||
#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) ()
|
||||
|
||||
@ -1538,6 +1548,9 @@ extern int target_search_memory (CORE_ADDR start_addr,
|
||||
#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))
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
2011-11-20 Stan Shebs <stan@codesourcery.com>
|
||||
|
||||
* gdb.trace/tstatus.exp: New.
|
||||
* gdb.trace/actions.c: Include string.h.
|
||||
|
||||
2011-11-18 Yao Qi <yao@codesourcery.com>
|
||||
|
||||
* gdb.trace/pending.exp: New.
|
||||
|
@ -2,6 +2,8 @@
|
||||
* Test program for trace action commands
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static char gdb_char_test;
|
||||
static short gdb_short_test;
|
||||
static long gdb_long_test;
|
||||
|
172
gdb/testsuite/gdb.trace/tstatus.exp
Normal file
172
gdb/testsuite/gdb.trace/tstatus.exp
Normal file
@ -0,0 +1,172 @@
|
||||
# Copyright 2011 Free Software Foundation, Inc.
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
load_lib "trace-support.exp"
|
||||
|
||||
set testfile "actions"
|
||||
set executable $testfile
|
||||
set srcfile $testfile.c
|
||||
set binfile $objdir/$subdir/$testfile
|
||||
set expfile tstatus.exp
|
||||
|
||||
if [prepare_for_testing $expfile $executable $srcfile \
|
||||
[list debug]] {
|
||||
untested "failed to prepare for trace tests"
|
||||
return -1
|
||||
}
|
||||
|
||||
if ![runto_main] {
|
||||
fail "Can't run to main to check for trace support"
|
||||
return -1
|
||||
}
|
||||
|
||||
if ![gdb_target_supports_trace] {
|
||||
unsupported "target does not support trace"
|
||||
return -1
|
||||
}
|
||||
|
||||
set libipa $objdir/../gdbserver/libinproctrace.so
|
||||
gdb_load_shlibs $libipa
|
||||
|
||||
# Can't use prepare_for_testing, because that splits compiling into
|
||||
# building objects and then linking, and we'd fail with "linker input
|
||||
# file unused because linking not done" when building the object.
|
||||
|
||||
if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
|
||||
executable [list debug shlib=$libipa] ] != "" } {
|
||||
untested "failed to compile ftrace tests"
|
||||
return -1
|
||||
}
|
||||
clean_restart ${executable}
|
||||
|
||||
if ![runto_main] {
|
||||
fail "Can't run to main for ftrace tests"
|
||||
return 0
|
||||
}
|
||||
|
||||
proc run_trace_experiment {} {
|
||||
|
||||
# gdb_test_no_output "set debug remote 1" ""
|
||||
|
||||
gdb_test "continue" \
|
||||
".*Breakpoint \[0-9\]+, begin .*" \
|
||||
"advance to trace begin"
|
||||
|
||||
gdb_test_no_output "tstart my tracing note" "start trace experiment"
|
||||
|
||||
gdb_test "continue" \
|
||||
".*Breakpoint \[0-9\]+, end .*" \
|
||||
"advance through tracing"
|
||||
|
||||
# Now play with tstatus a bit.
|
||||
# Since note support is optional, we need to match both with and without
|
||||
# cases.
|
||||
|
||||
gdb_test_multiple "tstatus" "check on trace status" {
|
||||
-re "Trace is running.*Trace will stop if GDB disconnects\.\[\r\n\]+Trace notes: my tracing note\.\[\r\n\]+Not looking at any trace frame\..*" {
|
||||
pass "tstatus reports trace note"
|
||||
}
|
||||
-re "Trace is running.*Trace will stop if GDB disconnects\.\[\r\n\]+Not looking at any trace frame.*" {
|
||||
pass "tstatus does not report any trace note"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "set trace-notes different note" "" "change tracing note"
|
||||
|
||||
gdb_test_multiple "tstatus" "check on trace status with diff note" {
|
||||
-re "Trace is running.*Trace will stop if GDB disconnects\.\[\r\n\]+Trace notes: different note\.\[\r\n\]+Not looking at any trace frame\..*" {
|
||||
pass "tstatus reports different trace note"
|
||||
}
|
||||
-re "Trace is running.*Trace will stop if GDB disconnects\.\[\r\n\]+Not looking at any trace frame.*" {
|
||||
pass "tstatus does not report any different trace note"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "set trace-user me me me" "" "change tracing user"
|
||||
|
||||
gdb_test_multiple "tstatus" "check on trace status with diff note" {
|
||||
-re "Trace is running.*Trace will stop if GDB disconnects\.\[\r\n\]+Trace user is me me me\.\[\r\n\]+Trace notes: different note\.\[\r\n\]+Not looking at any trace frame\..*" {
|
||||
pass "tstatus reports trace user"
|
||||
}
|
||||
-re "Trace is running.*Trace will stop if GDB disconnects\.\[\r\n\]+Not looking at any trace frame.*" {
|
||||
pass "tstatus does not report trace user"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test_no_output "tstop because I can" "trace stopped with note"
|
||||
|
||||
gdb_test_multiple "tstatus" "check on trace status after stop" {
|
||||
-re "Trace stopped by a tstop command (because I can)\..*Trace will stop if GDB disconnects\.\[\r\n\]+Trace user is me me me\.\[\r\n\]+Trace notes: different note\.\[\r\n\]+Not looking at any trace frame\..*" {
|
||||
pass "tstatus reports trace stop reason"
|
||||
}
|
||||
-re "Trace stopped by a tstop command\..*" {
|
||||
pass "tstatus does not report trace stop reason"
|
||||
}
|
||||
}
|
||||
|
||||
# Tracepoint hit count is optional, so pass it either way.
|
||||
|
||||
gdb_test_multiple "info trace" "show tracepoint state" {
|
||||
-re "actions\.c:\[0-9\]+\[\r\n\]+\[\t ]+tracepoint already hit 1 time\[\r\n\]+\[\t ]+collect parm" {
|
||||
pass "info trace reports tracepoint hit count"
|
||||
}
|
||||
-re "actions\.c:\[0-9\]+\[\r\n\]+\[\t ]+collect parm" {
|
||||
pass "info trace does not report tracepoint hit count"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc test_tracepoints {} {
|
||||
|
||||
gdb_test "break begin" ".*" ""
|
||||
|
||||
gdb_test "break end" ".*" ""
|
||||
|
||||
gdb_test "trace gdb_c_test" "Tracepoint .*" \
|
||||
"tracepoint at gdb_c_test"
|
||||
|
||||
gdb_trace_setactions "collect at set_point: define actions" \
|
||||
"" \
|
||||
"collect parm" "^$"
|
||||
set fastgood 0
|
||||
|
||||
gdb_test_multiple "ftrace gdb_recursion_test" "set fast tracepoint" {
|
||||
-re "May not have a fast tracepoint at .*" {
|
||||
pass "4-byte fast tracepoint could not be set"
|
||||
}
|
||||
-re "Fast tracepoint .*" {
|
||||
pass "4-byte fast tracepoint is set"
|
||||
set fastgood 1
|
||||
}
|
||||
}
|
||||
|
||||
if { $fastgood } {
|
||||
|
||||
gdb_trace_setactions "collect at four_byter: define actions" \
|
||||
"" \
|
||||
"collect globvar, anarg" "^$"
|
||||
}
|
||||
|
||||
run_trace_experiment
|
||||
|
||||
}
|
||||
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
|
||||
if { [gdb_test "info sharedlibrary" ".*libinproctrace\.so.*" "IPA loaded"] != 0 } {
|
||||
untested "Could not find IPA lib loaded"
|
||||
return 1
|
||||
}
|
||||
|
||||
test_tracepoints
|
@ -224,6 +224,7 @@ proc gdbserver_start { options arguments } {
|
||||
global gdbserver_reconnect_p
|
||||
if {![info exists gdbserver_reconnect_p] || !$gdbserver_reconnect_p} {
|
||||
# GDB client could accidentally connect to a stale server.
|
||||
# append gdbserver_command " --debug --once"
|
||||
append gdbserver_command " --once"
|
||||
}
|
||||
|
||||
|
316
gdb/tracepoint.c
316
gdb/tracepoint.c
@ -178,6 +178,18 @@ static int disconnected_tracing;
|
||||
|
||||
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);
|
||||
@ -199,8 +211,6 @@ static char *mem2hex (gdb_byte *, char *, int);
|
||||
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);
|
||||
|
||||
@ -1686,14 +1696,15 @@ process_tracepoint_on_disconnect (void)
|
||||
|
||||
|
||||
void
|
||||
start_tracing (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... */
|
||||
@ -1779,6 +1790,13 @@ start_tracing (void)
|
||||
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 ();
|
||||
|
||||
@ -1790,12 +1808,11 @@ start_tracing (void)
|
||||
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. */
|
||||
/* 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)
|
||||
@ -1809,23 +1826,37 @@ trace_start_command (char *args, int from_tty)
|
||||
error (_("New trace run not started."));
|
||||
}
|
||||
|
||||
start_tracing ();
|
||||
start_tracing (args);
|
||||
}
|
||||
|
||||
/* tstop command */
|
||||
/* 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 ();
|
||||
stop_tracing (args);
|
||||
}
|
||||
|
||||
void
|
||||
stop_tracing (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;
|
||||
}
|
||||
@ -1835,7 +1866,9 @@ static void
|
||||
trace_status_command (char *args, int from_tty)
|
||||
{
|
||||
struct trace_status *ts = current_trace_status ();
|
||||
int status;
|
||||
int status, ix;
|
||||
VEC(breakpoint_p) *tp_vec = NULL;
|
||||
struct breakpoint *t;
|
||||
|
||||
status = target_get_trace_status (ts);
|
||||
|
||||
@ -1866,7 +1899,11 @@ trace_status_command (char *args, int from_tty)
|
||||
printf_filtered (_("No trace has been run on the target.\n"));
|
||||
break;
|
||||
case tstop_command:
|
||||
printf_filtered (_("Trace stopped by a tstop command.\n"));
|
||||
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"));
|
||||
@ -1882,10 +1919,10 @@ trace_status_command (char *args, int from_tty)
|
||||
if (ts->stopping_tracepoint)
|
||||
printf_filtered (_("Trace stopped by an "
|
||||
"error (%s, tracepoint %d).\n"),
|
||||
ts->error_desc, ts->stopping_tracepoint);
|
||||
ts->stop_desc, ts->stopping_tracepoint);
|
||||
else
|
||||
printf_filtered (_("Trace stopped by an error (%s).\n"),
|
||||
ts->error_desc);
|
||||
ts->stop_desc);
|
||||
break;
|
||||
case trace_stop_reason_unknown:
|
||||
printf_filtered (_("Trace stopped for an unknown reason.\n"));
|
||||
@ -1936,12 +1973,46 @@ trace_status_command (char *args, int from_tty)
|
||||
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"));
|
||||
|
||||
/* Report start/stop times if supplied. */
|
||||
if (ts->start_time)
|
||||
{
|
||||
if (ts->stop_time)
|
||||
{
|
||||
LONGEST run_time = ts->stop_time - ts->start_time;
|
||||
|
||||
/* Reporting a run time is more readable than two long numbers. */
|
||||
printf_filtered (_("Trace started at %ld.%06ld secs, stopped %ld.%06ld secs later.\n"),
|
||||
ts->start_time / 1000000, ts->start_time % 1000000,
|
||||
run_time / 1000000, run_time % 1000000);
|
||||
}
|
||||
else
|
||||
printf_filtered (_("Trace started at %ld.%06ld secs.\n"),
|
||||
ts->start_time / 1000000, ts->start_time % 1000000);
|
||||
}
|
||||
else if (ts->stop_time)
|
||||
printf_filtered (_("Trace stopped at %ld.%06ld secs.\n"),
|
||||
ts->stop_time / 1000000, ts->stop_time % 1000000);
|
||||
|
||||
/* 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
|
||||
@ -2024,7 +2095,7 @@ trace_status_mi (int on_stop)
|
||||
stopping_tracepoint);
|
||||
if (ts->stop_reason == tracepoint_error)
|
||||
ui_out_field_string (uiout, "error-description",
|
||||
ts->error_desc);
|
||||
ts->stop_desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2040,6 +2111,20 @@ trace_status_mi (int on_stop)
|
||||
|
||||
ui_out_field_int (uiout, "disconnected", ts->disconnected_tracing);
|
||||
ui_out_field_int (uiout, "circular", ts->circular_buffer);
|
||||
|
||||
ui_out_field_string (uiout, "user-name", ts->user_name);
|
||||
ui_out_field_string (uiout, "notes", ts->notes);
|
||||
|
||||
{
|
||||
char buf[100];
|
||||
|
||||
xsnprintf (buf, sizeof buf, "%ld.%06ld",
|
||||
ts->start_time / 1000000, ts->start_time % 1000000);
|
||||
ui_out_field_string (uiout, "start-time", buf);
|
||||
xsnprintf (buf, sizeof buf, "%ld.%06ld",
|
||||
ts->stop_time / 1000000, ts->stop_time % 1000000);
|
||||
ui_out_field_string (uiout, "stop-time", buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* This function handles the details of what to do about an ongoing
|
||||
@ -2881,9 +2966,9 @@ trace_save (const char *filename, int target_does_save)
|
||||
(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);
|
||||
char *buf = (char *) alloca (strlen (ts->stop_desc) * 2 + 1);
|
||||
|
||||
bin2hex ((gdb_byte *) ts->error_desc, buf, 0);
|
||||
bin2hex ((gdb_byte *) ts->stop_desc, buf, 0);
|
||||
fprintf (fp, ":%s", buf);
|
||||
}
|
||||
fprintf (fp, ":%x", ts->stopping_tracepoint);
|
||||
@ -2935,6 +3020,9 @@ trace_save (const char *filename, int target_does_save)
|
||||
|
||||
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",
|
||||
@ -2971,6 +3059,11 @@ trace_save (const char *filename, int target_does_save)
|
||||
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);
|
||||
@ -3041,17 +3134,11 @@ trace_save_command (char *args, int from_tty)
|
||||
/* 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);
|
||||
target_set_disconnected_tracing (disconnected_tracing);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3061,6 +3148,42 @@ set_circular_trace_buffer (char *args, int from_tty,
|
||||
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
|
||||
@ -3638,20 +3761,26 @@ tfile_interp_line (char *line,
|
||||
void
|
||||
parse_trace_status (char *line, struct trace_status *ts)
|
||||
{
|
||||
char *p = line, *p1, *p2, *p_temp;
|
||||
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->error_desc);
|
||||
ts->error_desc = NULL;
|
||||
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;
|
||||
ts->start_time = ts->stop_time = 0;
|
||||
|
||||
while (*p++)
|
||||
{
|
||||
@ -3659,6 +3788,9 @@ parse_trace_status (char *line, struct trace_status *ts)
|
||||
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);
|
||||
@ -3678,7 +3810,22 @@ Status line: '%s'\n"), p, line);
|
||||
}
|
||||
else if (strncmp (p, stop_reason_names[tstop_command], p1 - p) == 0)
|
||||
{
|
||||
p = unpack_varlen_hex (++p1, &val);
|
||||
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)
|
||||
@ -3691,14 +3838,12 @@ Status line: '%s'\n"), p, line);
|
||||
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';
|
||||
ts->stop_desc = xmalloc ((p2 - p1) / 2 + 1);
|
||||
end = hex2bin (p1, ts->stop_desc, (p2 - p1) / 2);
|
||||
ts->stop_desc[end] = '\0';
|
||||
}
|
||||
else
|
||||
ts->error_desc = xstrdup ("");
|
||||
ts->stop_desc = xstrdup ("");
|
||||
|
||||
p = unpack_varlen_hex (++p2, &val);
|
||||
ts->stopping_tracepoint = val;
|
||||
@ -3734,6 +3879,32 @@ Status line: '%s'\n"), p, line);
|
||||
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. */
|
||||
@ -3747,6 +3918,26 @@ Status line: '%s'\n"), p, line);
|
||||
}
|
||||
}
|
||||
|
||||
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". */
|
||||
|
||||
@ -3848,6 +4039,12 @@ parse_tracepoint_definition (char *line, struct uploaded_tp **utpp)
|
||||
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
|
||||
@ -3923,6 +4120,13 @@ tfile_get_trace_status (struct trace_status *ts)
|
||||
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
|
||||
@ -4464,6 +4668,7 @@ init_tfile_ops (void)
|
||||
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;
|
||||
@ -5008,11 +5213,17 @@ De-select any trace frame and resume 'live' debugging."),
|
||||
add_com ("tstatus", class_trace, trace_status_command,
|
||||
_("Display the status of the current trace data collection."));
|
||||
|
||||
add_com ("tstop", class_trace, trace_stop_command,
|
||||
_("Stop trace data collection."));
|
||||
add_com ("tstop", class_trace, trace_stop_command, _("\
|
||||
Stop trace data collection.\n\
|
||||
Usage: tstop [ <notes> ... ]\n\
|
||||
Any arguments supplied are recorded with the trace as a stop reason and\n\
|
||||
reported by tstatus (if the target supports trace notes)."));
|
||||
|
||||
add_com ("tstart", class_trace, trace_start_command,
|
||||
_("Start trace data collection."));
|
||||
add_com ("tstart", class_trace, trace_start_command, _("\
|
||||
Start trace data collection.\n\
|
||||
Usage: tstart [ <notes> ... ]\n\
|
||||
Any arguments supplied are recorded with the trace as a note and\n\
|
||||
reported by tstatus (if the target supports trace notes)."));
|
||||
|
||||
add_com ("end", class_trace, end_actions_pseudocommand, _("\
|
||||
Ends a list of commands or actions.\n\
|
||||
@ -5087,6 +5298,27 @@ up and stopping the trace run."),
|
||||
&setlist,
|
||||
&showlist);
|
||||
|
||||
add_setshow_string_cmd ("trace-user", class_trace,
|
||||
&trace_user, _("\
|
||||
Set the user name to use for current and future trace runs"), _("\
|
||||
Show the user name to use for current and 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 current and future trace runs"), _("\
|
||||
Show the notes string to use for current and 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);
|
||||
|
@ -79,6 +79,7 @@ struct trace_status
|
||||
/* 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;
|
||||
@ -88,9 +89,11 @@ struct trace_status
|
||||
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;
|
||||
/* If stop_reason is tstop_command or tracepoint_error, this is an
|
||||
arbitrary string that may describe the reason for the stop in
|
||||
more detail. */
|
||||
|
||||
char *stop_desc;
|
||||
|
||||
/* Number of traceframes currently in the buffer. */
|
||||
|
||||
@ -117,6 +120,22 @@ struct trace_status
|
||||
target does not report a value, assume 0. */
|
||||
|
||||
int circular_buffer;
|
||||
|
||||
/* The "name" of the person running the trace. This is an
|
||||
arbitrary string. */
|
||||
|
||||
char *user_name;
|
||||
|
||||
/* "Notes" about the trace. This is an arbitrary string not
|
||||
interpreted by GDBserver in any special way. */
|
||||
|
||||
char *notes;
|
||||
|
||||
/* The calendar times at which the trace run started and stopped,
|
||||
both expressed in microseconds of Unix time. */
|
||||
|
||||
LONGEST start_time;
|
||||
LONGEST stop_time;
|
||||
};
|
||||
|
||||
struct trace_status *current_trace_status (void);
|
||||
@ -154,6 +173,12 @@ struct uploaded_tp
|
||||
/* List of original strings defining the tracepoint's actions. */
|
||||
VEC(char_ptr) *cmd_strings;
|
||||
|
||||
/* The tracepoint's current hit count. */
|
||||
int hit_count;
|
||||
|
||||
/* The tracepoint's current traceframe usage. */
|
||||
ULONGEST traceframe_usage;
|
||||
|
||||
struct uploaded_tp *next;
|
||||
};
|
||||
|
||||
@ -229,6 +254,9 @@ extern int encode_source_string (int num, ULONGEST addr,
|
||||
|
||||
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);
|
||||
@ -241,8 +269,8 @@ extern void merge_uploaded_trace_state_variables (struct uploaded_tsv **utsvp);
|
||||
|
||||
extern void disconnect_tracing (int from_tty);
|
||||
|
||||
extern void start_tracing (void);
|
||||
extern void stop_tracing (void);
|
||||
extern void start_tracing (char *notes);
|
||||
extern void stop_tracing (char *notes);
|
||||
|
||||
extern void trace_status_mi (int on_stop);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user