2010-03-18 Stan Shebs <stan@codesourcery.com>

Pedro Alves  <pedro@codesourcery.com>

	* target.h (struct target_ops): New method
	to_set_circular_trace_buffer.
	(target_set_circular_trace_buffer): New macro.
	* target.c (update_current_target): Add
	to_set_circular_trace_buffer, fix to_set_disconnected_tracing
	default behavior.
	* remote.c (remote_set_circular_trace_buffer): New function.
	(init_remote_ops): Add it to vector.
	* tracepoint.h (struct trace_status): New field traceframes_created,
	change buffer_size and buffer_free to int.
	* tracepoint.c (circular_trace_buffer): New global.
	(start_tracing): Send values of disconnected tracing and circular
	trace buffer settings.
	(set_circular_trace_buffer): New function.
	(parse_trace_state): Handle total space and frames created.
	(trace_status_command): Display total space and total frames
	created.
	(trace_save): Write out new status values.
	(parse_trace_status): Set traceframe_count, traceframes_created,
	buffer_free and buffer_size to -1 by default.
	(_initialize_tracepoint): New setshow for circular-trace-buffer.
	* NEWS: Mention the circular trace buffer option.

	* gdb.texinfo (Starting and Stopping Trace Experiments): Describe
	circular-trace-buffer.
	(Tracepoint Packets): Describe QTBuffer, and details of the
	qTStatus reply.

	* gdb.trace/circ.exp: Test circular-trace-buffer.
	* gdb.trace/tfile.exp: Update tstatus test.
This commit is contained in:
Stan Shebs 2010-03-18 21:23:35 +00:00
parent 576ee33af3
commit 4daf5ac07e
12 changed files with 269 additions and 20 deletions

View File

@ -1,3 +1,29 @@
2010-03-18 Stan Shebs <stan@codesourcery.com>
Pedro Alves <pedro@codesourcery.com>
* target.h (struct target_ops): New method
to_set_circular_trace_buffer.
(target_set_circular_trace_buffer): New macro.
* target.c (update_current_target): Add
to_set_circular_trace_buffer, fix to_set_disconnected_tracing
default behavior.
* remote.c (remote_set_circular_trace_buffer): New function.
(init_remote_ops): Add it to vector.
* tracepoint.h (struct trace_status): New field traceframes_created,
change buffer_size and buffer_free to int.
* tracepoint.c (circular_trace_buffer): New global.
(start_tracing): Send values of disconnected tracing and circular
trace buffer settings.
(set_circular_trace_buffer): New function.
(parse_trace_state): Handle total space and frames created.
(trace_status_command): Display total space and total frames
created.
(trace_save): Write out new status values.
(parse_trace_status): Set traceframe_count, traceframes_created,
buffer_free and buffer_size to -1 by default.
(_initialize_tracepoint): New setshow for circular-trace-buffer.
* NEWS: Mention the circular trace buffer option.
2010-03-18 Tom Tromey <tromey@redhat.com>
* infcmd.c (finish_command_continuation): Wrap print_return_value

View File

@ -114,7 +114,14 @@ Renesas RX rx
tracing run at the moment that it was saved. To create a trace
file, use "tsave <filename>", and to use it, do "target tfile
<name>".
** Circular trace buffer
You can ask the target agent to handle the trace buffer as a
circular buffer, discarding the oldest trace frames to make room for
newer ones, by setting circular-trace-buffer to on. This feature may
not be available for all target agents.
* Changed commands
disassemble
@ -215,6 +222,13 @@ show disconnected-tracing
loses its connection to GDB. If 0, the target is to stop tracing
upon disconnection.
set circular-trace-buffer
show circular-trace-buffer
If set to on, the target is instructed to use a circular trace buffer
and discard the oldest trace frames instead of stopping the trace due
to a full trace buffer. If set to off, the trace stops when the buffer
fills up. Some targets may not support this.
set script-extension off|soft|strict
show script-extension
If set to "off", the debugger does not perform any script language
@ -258,6 +272,9 @@ qTV
QTDisconnected
Set desired tracing behavior upon disconnection.
QTBuffer:circular
Set the trace buffer to be linear or circular.
qTfP, qTsP
Get data about the tracepoints currently in use.

View File

@ -1,3 +1,10 @@
2010-03-16 Stan Shebs <stan@codesourcery.com>
* gdb.texinfo (Starting and Stopping Trace Experiments): Describe
circular-trace-buffer.
(Tracepoint Packets): Describe QTBuffer, and details of the
qTStatus reply.
2010-03-12 Stan Shebs <stan@codesourcery.com>
Nathan Sidwell <nathan@codesourcery.com>

View File

@ -9836,6 +9836,37 @@ which to specify that tracepoint. This matching-up process is
necessarily heuristic, and it may result in useless tracepoints being
created; you may simply delete them if they are of no use.
@cindex circular trace buffer
If your target agent supports a @dfn{circular trace buffer}, then you
can run a trace experiment indefinitely without filling the trace
buffer; when space runs out, the agent deletes already-collected trace
frames, oldest first, until there is enough room to continue
collecting. This is especially useful if your tracepoints are being
hit too often, and your trace gets terminated prematurely because the
buffer is full. To ask for a circular trace buffer, simply set
@samp{circular_trace_buffer} to on. You can set this at any time,
including during tracing; if the agent can do it, it will change
buffer handling on the fly, otherwise it will not take effect until
the next run.
@table @code
@item set circular-trace-buffer on
@itemx set circular-trace-buffer off
@kindex set circular-trace-buffer
Choose whether a tracing run should use a linear or circular buffer
for trace data. A linear buffer will not lose any trace data, but may
fill up prematurely, while a circular buffer will discard old trace
data, but it will have always room for the latest tracepoint hits.
@item show circular-trace-buffer
@kindex show circular-trace-buffer
Show the current choice for the trace buffer. Note that this may not
match the agent's current buffer handling, nor is it guaranteed to
match the setting that might have been in effect during a past run,
for instance if you are looking at frames from a trace file.
@end table
@node Tracepoint Restrictions
@subsection Tracepoint Restrictions
@ -30603,6 +30634,7 @@ encoded). @value{GDBN} will continue to supply the values of symbols
@end table
@item qTBuffer
@item QTBuffer
@item QTDisconnected
@itemx QTDP
@itemx QTDV
@ -31087,12 +31119,62 @@ continue the tracing run, while 0 tells the target to stop tracing if
@item qTStatus
Ask the stub if there is a trace experiment running right now.
Replies:
The reply has the form:
@table @samp
@item T0
There is no trace experiment running.
@item T1
There is a trace experiment running.
@item T@var{running}@r{[};@var{field}@r{]}@dots{}
@var{running} is a single digit @code{1} if the trace is presently
running, or @code{0} if not. It is followed by semicolon-separated
optional fields that an agent may use to report additional status.
@end table
If the trace is not running, the agent may report any of several
explanations as one of the optional fields:
@table @samp
@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.
@item tdisconnected:0
The trace stopped because @value{GDBN} disconnected from the target.
@item tpasscount:@var{tpnum}
The trace stopped because tracepoint @var{tpnum} exceeded its pass count.
@item tunknown:0
The trace stopped for some other reason.
@end table
Additional optional fields supply statistical information. Although
not required, they are extremely useful for users monitoring the
progress of a trace run. If a trace has stopped, and these numbers
are reported, they must reflect the state of the just-stopped trace.
@table @samp
@item tframes:@var{n}
The number of trace frames in the buffer.
@item tcreated:@var{n}
The total number of trace frames created during the run. This may
be larger than the trace frame count, if the buffer is circular.
@item tsize:@var{n}
The total size of the trace buffer, in bytes.
@item tfree:@var{n}
The number of bytes still unused in the buffer.
@end table
@item qTV:@var{var}
@ -31147,6 +31229,10 @@ in a packet; it is not an error to return fewer than were asked for.
A reply consisting of just @code{l} indicates that no bytes are
available.
@item QTBuffer:circular:@var{value}
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.
@end table
@node Host I/O Packets

View File

@ -9658,6 +9658,18 @@ remote_core_of_thread (struct target_ops *ops, ptid_t ptid)
return -1;
}
static void
remote_set_circular_trace_buffer (int val)
{
struct remote_state *rs = get_remote_state ();
sprintf (rs->buf, "QTBuffer:circular:%x", val);
putpkt (rs->buf);
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Target does not support this command."));
}
static void
init_remote_ops (void)
{
@ -9736,6 +9748,7 @@ Specify the serial device it is connected to\n\
remote_ops.to_upload_trace_state_variables = remote_upload_trace_state_variables;
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_core_of_thread = remote_core_of_thread;
}

View File

@ -659,6 +659,7 @@ update_current_target (void)
INHERIT (to_upload_trace_state_variables, t);
INHERIT (to_get_raw_trace_data, t);
INHERIT (to_set_disconnected_tracing, t);
INHERIT (to_set_circular_trace_buffer, t);
INHERIT (to_magic, t);
/* Do not inherit to_memory_map. */
/* Do not inherit to_flash_erase. */
@ -848,7 +849,10 @@ update_current_target (void)
tcomplain);
de_fault (to_set_disconnected_tracing,
(void (*) (int))
tcomplain);
target_ignore);
de_fault (to_set_circular_trace_buffer,
(void (*) (int))
target_ignore);
#undef de_fault
/* Finally, position the target-stack beneath the squashed

View File

@ -664,6 +664,7 @@ struct target_ops
/* Set the target's tracing behavior in response to unexpected
disconnection - set VAL to 1 to keep tracing, 0 to stop. */
void (*to_set_disconnected_tracing) (int val);
void (*to_set_circular_trace_buffer) (int val);
/* Return the processor core that thread PTID was last seen on.
This information is updated only when:
@ -1359,6 +1360,9 @@ extern int target_search_memory (CORE_ADDR start_addr,
#define target_set_disconnected_tracing(val) \
(*current_target.to_set_disconnected_tracing) (val)
#define target_set_circular_trace_buffer(val) \
(*current_target.to_set_circular_trace_buffer) (val)
/* Command logging facility. */
#define target_log_command(p) \

View File

@ -1,3 +1,8 @@
2010-03-18 Stan Shebs <stan@codesourcery.com>
* gdb.trace/circ.exp: Test circular-trace-buffer.
* gdb.trace/tfile.exp: Update tstatus test.
2010-03-18 Joel Brobecker <brobecker@adacore.com>
* gdb.dwarf2/dw2-anonymous-func.S: New file.

View File

@ -197,6 +197,15 @@ gdb_load $binfile
if [target_info exists gdb_stub] {
gdb_step_for_stub;
}
gdb_test "set circular-trace-buffer on" "" "set circular-trace-buffer on"
gdb_test "show circular-trace-buffer" "Target's use of circular trace buffer is on." "show circular-trace-buffer (on)"
gdb_test "set circular-trace-buffer off" "" "set circular-trace-buffer off"
gdb_test "show circular-trace-buffer" "Target's use of circular trace buffer is off." "show circular-trace-buffer (off)"
# Body of test encased in a proc so we can return prematurely.
if { ![gdb_trace_circular_tests] } then {
# Set trace buffer attributes back to normal

View File

@ -78,8 +78,8 @@ gdb_test "tfind" "Target failed to find requested trace frame." \
gdb_test "tstatus" \
"Using a trace file.*
Trace stopped by a tstop command.*
Collected 1 trace frames.*
Trace buffer has 256 bytes free.*
Collected 1 trace frame.*
Trace buffer has 256 bytes of 4096 bytes free \\(93% full\\).*
Looking at trace frame 0, tracepoint .*" \
"tstatus on trace file"

View File

@ -153,6 +153,11 @@ char *default_collect = "";
static int disconnected_tracing;
/* This variable controls whether we ask the target for a linear or
circular trace buffer. */
static int circular_trace_buffer;
/* ======= Important command functions: ======= */
static void trace_actions_command (char *, int);
static void trace_start_command (char *, int);
@ -1579,6 +1584,9 @@ trace_start_command (char *args, int from_tty)
/* Tell target to treat text-like sections as transparent. */
target_trace_set_readonly_regions ();
/* Set some mode flags. */
target_set_disconnected_tracing (disconnected_tracing);
target_set_circular_trace_buffer (circular_trace_buffer);
/* Now insert traps and begin collecting data. */
target_trace_start ();
@ -1668,16 +1676,34 @@ trace_status_command (char *args, int from_tty)
}
}
if (ts->traceframe_count >= 0)
if (ts->traceframes_created >= 0
&& ts->traceframe_count != ts->traceframes_created)
{
printf_filtered (_("Buffer contains %d trace frames (of %d created total).\n"),
ts->traceframe_count, ts->traceframes_created);
}
else if (ts->traceframe_count >= 0)
{
printf_filtered (_("Collected %d trace frames.\n"),
ts->traceframe_count);
}
if (ts->buffer_free)
if (ts->buffer_free >= 0)
{
printf_filtered (_("Trace buffer has %llu bytes free.\n"),
ts->buffer_free);
if (ts->buffer_size >= 0)
{
printf_filtered (_("Trace buffer has %d bytes of %d bytes free"),
ts->buffer_free, ts->buffer_size);
if (ts->buffer_size > 0)
printf_filtered (_(" (%d%% full)"),
((int) ((((long long) (ts->buffer_size
- ts->buffer_free)) * 100)
/ ts->buffer_size)));
printf_filtered (_(".\n"));
}
else
printf_filtered (_("Trace buffer has %d bytes free.\n"),
ts->buffer_free);
}
/* Now report on what we're doing with tfind. */
@ -2438,10 +2464,18 @@ trace_save_command (char *args, int from_tty)
fprintf (fp, "R %x\n", trace_regblock_size);
/* Write out status of the tracing run (aka "tstatus" info). */
fprintf (fp, "status %c;%s:%x;tframes:%x;tfree:%llx\n",
fprintf (fp, "status %c;%s:%x",
(ts->running ? '1' : '0'),
stop_reason_names[ts->stop_reason], ts->stopping_tracepoint,
ts->traceframe_count, ts->buffer_free);
stop_reason_names[ts->stop_reason], ts->stopping_tracepoint);
if (ts->traceframe_count >= 0)
fprintf (fp, ";tframes:%x", ts->traceframe_count);
if (ts->traceframes_created >= 0)
fprintf (fp, ";tcreated:%x", ts->traceframes_created);
if (ts->buffer_free >= 0)
fprintf (fp, ";tfree:%x", ts->buffer_free);
if (ts->buffer_size >= 0)
fprintf (fp, ";tsize:%x", ts->buffer_size);
fprintf (fp, "\n");
/* Note that we want to upload tracepoints and save those, rather
than simply writing out the local ones, because the user may have
@ -2546,6 +2580,13 @@ set_disconnected_tracing (char *args, int from_tty,
send_disconnected_tracing_value (disconnected_tracing);
}
static void
set_circular_trace_buffer (char *args, int from_tty,
struct cmd_list_element *c)
{
target_set_circular_trace_buffer (circular_trace_buffer);
}
/* 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
@ -3059,6 +3100,11 @@ parse_trace_status (char *line, struct trace_status *ts)
ts->running_known = 1;
ts->running = (*p++ == '1');
ts->stop_reason = trace_stop_reason_unknown;
ts->traceframe_count = -1;
ts->traceframes_created = -1;
ts->buffer_free = -1;
ts->buffer_size = -1;
while (*p++)
{
p1 = strchr (p, ':');
@ -3086,16 +3132,26 @@ Status line: '%s'\n"), p, line);
p = unpack_varlen_hex (++p1, &val);
ts->stop_reason = tstop_command;
}
if (strncmp (p, "tframes", p1 - p) == 0)
else if (strncmp (p, "tframes", p1 - p) == 0)
{
p = unpack_varlen_hex (++p1, &val);
ts->traceframe_count = val;
}
if (strncmp (p, "tfree", p1 - p) == 0)
else if (strncmp (p, "tcreated", p1 - p) == 0)
{
p = unpack_varlen_hex (++p1, &val);
ts->traceframes_created = val;
}
else if (strncmp (p, "tfree", p1 - p) == 0)
{
p = unpack_varlen_hex (++p1, &val);
ts->buffer_free = val;
}
else if (strncmp (p, "tsize", p1 - p) == 0)
{
p = unpack_varlen_hex (++p1, &val);
ts->buffer_size = val;
}
else
{
/* Silently skip unknown optional info. */
@ -3819,6 +3875,18 @@ trace data collected in the meantime."),
&setlist,
&showlist);
add_setshow_boolean_cmd ("circular-trace-buffer", no_class,
&circular_trace_buffer, _("\
Set target's use of circular trace buffer."), _("\
Show target's use of circular trace buffer."), _("\
Use this to make the trace buffer into a circular buffer,\n\
which will discard traceframes (oldest first) instead of filling\n\
up and stopping the trace run."),
set_circular_trace_buffer,
NULL,
&setlist,
&showlist);
init_tfile_ops ();
add_target (&tfile_ops);

View File

@ -95,11 +95,21 @@ struct trace_status
int stopping_tracepoint;
/* Number of traceframes currently in the buffer. */
int traceframe_count;
unsigned long long buffer_size;
/* Number of traceframes created since start of run. */
unsigned long long buffer_free;
int traceframes_created;
/* Total size of the target's trace buffer. */
int buffer_size;
/* Unused bytes left in the target's trace buffer. */
int buffer_free;
};
struct trace_status *current_trace_status (void);